diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 35 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/constructors.cpp | 2 | ||||
| -rw-r--r-- | clang/test/SemaCXX/zero-length-arrays.cpp | 26 |
3 files changed, 53 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 61385f93481..7a423a73f05 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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>(); diff --git a/clang/test/CodeGenCXX/constructors.cpp b/clang/test/CodeGenCXX/constructors.cpp index ec7f06c868a..9e2da31f046 100644 --- a/clang/test/CodeGenCXX/constructors.cpp +++ b/clang/test/CodeGenCXX/constructors.cpp @@ -111,7 +111,5 @@ namespace test1 { B::B() {} // CHECK: define void @_ZN5test11BC2Ev( // CHECK: [[THIS:%.*]] = load [[B:%.*]]** - // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[B:%.*]]* [[THIS]], i32 0, i32 1 - // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [0 x {{%.*}}]* [[A]], i32 0, i32 0 // CHECK-NEXT: ret void } diff --git a/clang/test/SemaCXX/zero-length-arrays.cpp b/clang/test/SemaCXX/zero-length-arrays.cpp new file mode 100644 index 00000000000..05ded4ad9b3 --- /dev/null +++ b/clang/test/SemaCXX/zero-length-arrays.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// <rdar://problem/10228639> +class Foo { + ~Foo(); + Foo(const Foo&); +public: + Foo(int); +}; + +class Bar { + int foo_count; + Foo foos[0]; + Foo foos2[0][2]; + Foo foos3[2][0]; + +public: + Bar(): foo_count(0) { } + ~Bar() { } +}; + +void testBar() { + Bar b; + Bar b2(b); + b = b2; +} |

