summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-05-07 05:20:46 +0000
committerJohn McCall <rjmccall@apple.com>2013-05-07 05:20:46 +0000
commit6054d5aa7b35a4d2274fd999acfb499d9f796789 (patch)
tree4e4c518762702897693b616ff3ae563f0930075d /clang
parent790ede43decb29c2938d342cae663cd64b1fb557 (diff)
downloadbcm5719-llvm-6054d5aa7b35a4d2274fd999acfb499d9f796789.tar.gz
bcm5719-llvm-6054d5aa7b35a4d2274fd999acfb499d9f796789.zip
Weaken an assertion in memcpyization to account for
unnamed bitfields. Unnamed bitfields won't have an explicit copy operation in the AST, which breaks the strong form of the invariant. rdar://13816940 llvm-svn: 181289
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp8
-rw-r--r--clang/test/CodeGenCXX/copy-constructor-synthesis.cpp41
2 files changed, 47 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 3fd075701d0..e4180a0d72d 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -859,8 +859,12 @@ namespace {
}
void addNextField(FieldDecl *F) {
- assert(F->getFieldIndex() == LastAddedFieldIndex + 1 &&
- "Cannot aggregate non-contiguous fields.");
+ // For the most part, the following invariant will hold:
+ // F->getFieldIndex() == LastAddedFieldIndex + 1
+ // The one exception is that Sema won't add a copy-initializer for an
+ // unnamed bitfield, which will show up here as a gap in the sequence.
+ assert(F->getFieldIndex() >= LastAddedFieldIndex + 1 &&
+ "Cannot aggregate fields out of order.");
LastAddedFieldIndex = F->getFieldIndex();
// The 'first' and 'last' fields are chosen by offset, rather than field
diff --git a/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp b/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp
index 68f680574b7..f6c38219517 100644
--- a/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp
+++ b/clang/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -136,6 +136,32 @@ void f(B b1) {
B b2 = b1;
}
+// CHECK: define linkonce_odr [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_(
+// CHECK: [[THIS:%.*]] = load [[A]]**
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
+// CHECK-NEXT: [[T1:%.*]] = bitcast [2 x i8]* [[T0]] to i16*
+// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]**
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1
+// CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8]* [[T2]] to i16*
+// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T1]] to i8*
+// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T3]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false)
+// CHECK-NEXT: ret [[A]]* [[THIS]]
+
+// CHECK: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_(
+// CHECK: [[THIS:%.*]] = load [[A]]**
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i8***
+// CHECK-NEXT: store i8** getelementptr inbounds ([4 x i8*]* @_ZTVN12rdar138169401AE, i64 0, i64 2), i8*** [[T0]]
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
+// CHECK-NEXT: [[T1:%.*]] = bitcast [2 x i8]* [[T0]] to i16*
+// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]**
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1
+// CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8]* [[T2]] to i16*
+// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T1]] to i8*
+// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T3]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false)
+// CHECK-NEXT: ret void
+
// CHECK: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"*) unnamed_addr
// CHECK: call void @_ZN6PR66281TC1Ev
// CHECK: call void @_ZN6PR66281TC1Ev
@@ -154,3 +180,18 @@ void f(B b1) {
// CHECK: call void @_ZN6PR66281TD1Ev
}
+// rdar://13816940
+// Test above because things get weirdly re-ordered.
+namespace rdar13816940 {
+ struct A {
+ virtual ~A();
+ unsigned short a : 1;
+ unsigned short : 15;
+ unsigned other;
+ };
+
+ void test(A &a) {
+ A x = a; // force copy constructor into existence
+ x = a; // also force the copy assignment operator
+ }
+}
OpenPOWER on IntegriCloud