diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-11-02 23:04:16 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-11-02 23:04:16 +0000 |
commit | ddb21473ef1ff20b3abf7ba3cd6cb29acbd5cf06 (patch) | |
tree | f2fb24e81bce77ba33239a187e2a060d550b1429 /lib/Sema/SemaDeclCXX.cpp | |
parent | c637d738897b1745af3bad7fc551f26b98da838c (diff) |
Don't build member initializers for zero-length or incomplete arrays,
and don't try to destroy them, either. Fixes
<rdar://problem/10228639>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143584 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 61385f9348..7a423a73f0 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2413,7 +2413,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, // Suppress copying zero-width bitfields. if (Field->isBitField() && Field->getBitWidthValue(SemaRef.Context) == 0) return false; - + Expr *MemberExprBase = DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), Param, Loc, ParamType, VK_LValue, 0); @@ -2649,6 +2649,22 @@ static bool isWithinAnonymousUnion(IndirectFieldDecl *F) { return false; } +/// \brief Determine whether the given type is an incomplete or zero-lenfgth +/// array type. +static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) { + if (T->isIncompleteArrayType()) + return true; + + while (const ConstantArrayType *ArrayT = Context.getAsConstantArrayType(T)) { + if (!ArrayT->getSize()) + return true; + + T = ArrayT->getElementType(); + } + + return false; +} + static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info, FieldDecl *Field, IndirectFieldDecl *Indirect = 0) { @@ -2684,6 +2700,10 @@ static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info, (Indirect && isWithinAnonymousUnion(Indirect))) return false; + // Don't initialize incomplete or zero-length arrays. + if (isIncompleteOrZeroLengthArrayType(SemaRef.Context, Field->getType())) + return false; + // Don't try to build an implicit initializer if there were semantic // errors in any of the initializers (and therefore we might be // missing some that the user actually wrote). @@ -2822,13 +2842,7 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, // initialized. if (F->isUnnamedBitfield()) continue; - - if (F->getType()->isIncompleteArrayType()) { - assert(ClassDecl->hasFlexibleArrayMember() && - "Incomplete array type is not valid"); - continue; - } - + // If we're not generating the implicit copy/move constructor, then we'll // handle anonymous struct/union fields based on their individual // indirect fields. @@ -3169,6 +3183,11 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location, FieldDecl *Field = *I; if (Field->isInvalidDecl()) continue; + + // Don't destroy incomplete or zero-length arrays. + if (isIncompleteOrZeroLengthArrayType(Context, Field->getType())) + continue; + QualType FieldType = Context.getBaseElementType(Field->getType()); const RecordType* RT = FieldType->getAs<RecordType>(); |