[cfe-commits] r143584 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/CodeGenCXX/constructors.cpp test/SemaCXX/zero-length-arrays.cpp
Douglas Gregor
dgregor at apple.com
Wed Nov 2 16:04:17 PDT 2011
Author: dgregor
Date: Wed Nov 2 18:04:16 2011
New Revision: 143584
URL: http://llvm.org/viewvc/llvm-project?rev=143584&view=rev
Log:
Don't build member initializers for zero-length or incomplete arrays,
and don't try to destroy them, either. Fixes
<rdar://problem/10228639>.
Added:
cfe/trunk/test/SemaCXX/zero-length-arrays.cpp
Modified:
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CodeGenCXX/constructors.cpp
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=143584&r1=143583&r2=143584&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Nov 2 18:04:16 2011
@@ -2413,7 +2413,7 @@
// 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 @@
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 @@
(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 @@
// 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 @@
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>();
Modified: cfe/trunk/test/CodeGenCXX/constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/constructors.cpp?rev=143584&r1=143583&r2=143584&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/constructors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/constructors.cpp Wed Nov 2 18:04:16 2011
@@ -111,7 +111,5 @@
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
}
Added: cfe/trunk/test/SemaCXX/zero-length-arrays.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/zero-length-arrays.cpp?rev=143584&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/zero-length-arrays.cpp (added)
+++ cfe/trunk/test/SemaCXX/zero-length-arrays.cpp Wed Nov 2 18:04:16 2011
@@ -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;
+}
More information about the cfe-commits
mailing list