forked from OSchip/llvm-project
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
This commit is contained in:
parent
790ede43de
commit
6054d5aa7b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue