llvm-project/clang/test/CodeGenCXX/anonymous-union-member-initializer.cpp
Douglas Gregor 493627ba8b Rewrite default initialization of anonymous structs/unions within a
constructor. Previously, we did some bogus recursion into the fields
of anonymous structs (recursively), which ended up building invalid
ASTs that would cause CodeGen to crash due to invalid GEPs.

Now, we instead build the default initializations based on the
indirect field declarations at the top level, which properly generates
the sequence of GEPs needed to initialize the proper member. Fixes
PR10512 and <rdar://problem/9924046>.

llvm-svn: 137212
2011-08-10 15:22:55 +00:00

182 lines
4.1 KiB
C++

// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
// rdar://8818236
namespace rdar8818236 {
struct S {
char c2;
union {
char c;
int i;
};
};
// CHECK: @_ZN11rdar88182363fooE = global i64 4
char S::*foo = &S::c;
}
struct A {
union {
int a;
void* b;
};
A() : a(0) { }
};
A a;
namespace PR7021 {
struct X
{
union { long l; };
};
// CHECK: define void @_ZN6PR70211fENS_1XES0_
void f(X x, X z) {
X x1;
// CHECK: store i64 1, i64
x1.l = 1;
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
X x2(x1);
X x3;
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
x3 = x1;
// CHECK: ret void
}
}
namespace test2 {
struct A {
struct {
union {
int b;
};
};
A();
};
A::A() : b(10) { }
// CHECK: define void @_ZN5test21AC2Ev(
// CHECK-NOT: }
// CHECK: store i32 10
// CHECK: }
}
namespace PR10512 {
struct A {
A();
A(int);
A(long);
struct {
struct {int x;};
struct {int y;};
};
};
// CHECK: define void @_ZN7PR105121AC2Ev
// CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
// CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
// CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]]
// CHECK-NEXT: ret void
A::A() {}
// CHECK: define void @_ZN7PR105121AC2Ei
// CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
// CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i32
// CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
// CHECK-NEXT: store i32 [[X:%[a-zA-z0-9.]+]], i32* [[XADDR]]
// CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]]
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i32* [[XADDR]]
// CHECK-NEXT: store i32 [[TMP]]
// CHECK-NEXT: ret void
A::A(int x) : x(x) { }
// CHECK: define void @_ZN7PR105121AC2El
// CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
// CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i64
// CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
// CHECK-NEXT: store i64 [[X:%[a-zA-z0-9.]+]], i64* [[XADDR]]
// CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]]
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 1}}
// CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
// CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i64* [[XADDR]]
// CHECK-NEXT: [[CONV:%[a-zA-z0-9.]+]] = trunc i64 [[TMP]] to i32
// CHECK-NEXT: store i32 [[CONV]]
// CHECK-NEXT: ret void
A::A(long y) : y(y) { }
}
namespace test3 {
struct A {
union {
mutable char fibers[100];
struct {
void (*callback)(void*);
void *callback_value;
};
};
A();
};
A::A() : callback(0), callback_value(0) {}
// CHECK: define void @_ZN5test31AC2Ev(
// CHECK: [[THIS:%.*]] = load
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
// CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
// CHECK: store
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
// CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1
// CHECK-NEXT: store i8* null, i8** [[CVALUE]]
}
struct S {
// CHECK: store i32 42
// CHECK: store i32 55
S() : x(42), y(55) {}
union {
struct {
int x;
union { int y; };
};
};
} s;
//PR8760
template <typename T> struct Foo {
Foo() : ptr(__nullptr) {}
union {
T *ptr;
};
};
Foo<int> f;
namespace PR9683 {
struct QueueEntry {
union {
struct {
void* mPtr;
union {
unsigned mSubmissionTag;
};
};
unsigned mValue;
};
QueueEntry() {}
};
QueueEntry QE;
}