1 // RUN: %clang_cc1 %s -emit-llvm -o %t.ll -triple=x86_64-apple-darwin10
2 // RUN: FileCheck %s < %t.ll
3 // RUN: FileCheck -check-prefix=CHECK-GLOBAL %s < %t.ll
4
5 struct A { int a; int b; };
6 struct B { int b; };
7 struct C : B, A { };
8
9 // Zero init.
10 namespace ZeroInit {
11 // CHECK-GLOBAL: @_ZN8ZeroInit1aE = global i64 -1
12 int A::* a;
13
14 // CHECK-GLOBAL: @_ZN8ZeroInit2aaE = global [2 x i64] [i64 -1, i64 -1]
15 int A::* aa[2];
16
17 // CHECK-GLOBAL: @_ZN8ZeroInit3aaaE = global [2 x [2 x i64]] {{\[}}[2 x i64] [i64 -1, i64 -1], [2 x i64] [i64 -1, i64 -1]]
18 int A::* aaa[2][2];
19
20 // CHECK-GLOBAL: @_ZN8ZeroInit1bE = global i64 -1,
21 int A::* b = 0;
22
23 // CHECK-GLOBAL: @_ZN8ZeroInit2saE = internal global %struct.anon { i64 -1 }
24 struct {
25 int A::*a;
26 } sa;
test_sa()27 void test_sa() { (void) sa; } // force emission
28
29 // CHECK-GLOBAL: @_ZN8ZeroInit3ssaE = internal
30 // CHECK-GLOBAL: [2 x i64] [i64 -1, i64 -1]
31 struct {
32 int A::*aa[2];
33 } ssa[2];
test_ssa()34 void test_ssa() { (void) ssa; }
35
36 // CHECK-GLOBAL: @_ZN8ZeroInit2ssE = internal global %struct.anon.1 { %struct.anon.2 { i64 -1 } }
37 struct {
38 struct {
39 int A::*pa;
40 } s;
41 } ss;
test_ss()42 void test_ss() { (void) ss; }
43
44 struct A {
45 int A::*a;
46 int b;
47 };
48
49 struct B {
50 A a[10];
51 char c;
52 int B::*b;
53 };
54
55 struct C : A, B { int j; };
56 // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} <{ %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::B" { [10 x %"struct.ZeroInit::A"] [%"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }], i8 0, i64 -1 }, i32 0, [4 x i8] zeroinitializer }>, align 8
57 C c;
58 }
59
60 // PR5674
61 namespace PR5674 {
62 // CHECK-GLOBAL: @_ZN6PR56742pbE = global i64 4
63 int A::*pb = &A::b;
64 }
65
66 // Casts.
67 namespace Casts {
68
69 int A::*pa;
70 int C::*pc;
71
f()72 void f() {
73 // CHECK: store i64 -1, i64* @_ZN5Casts2paE
74 pa = 0;
75
76 // CHECK-NEXT: [[TMP:%.*]] = load i64, i64* @_ZN5Casts2paE, align 8
77 // CHECK-NEXT: [[ADJ:%.*]] = add nsw i64 [[TMP]], 4
78 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1
79 // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]
80 // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2pcE
81 pc = pa;
82
83 // CHECK-NEXT: [[TMP:%.*]] = load i64, i64* @_ZN5Casts2pcE, align 8
84 // CHECK-NEXT: [[ADJ:%.*]] = sub nsw i64 [[TMP]], 4
85 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1
86 // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]
87 // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2paE
88 pa = static_cast<int A::*>(pc);
89 }
90
91 }
92
93 // Comparisons
94 namespace Comparisons {
f()95 void f() {
96 int A::*a;
97
98 // CHECK: icmp ne i64 {{.*}}, -1
99 if (a) { }
100
101 // CHECK: icmp ne i64 {{.*}}, -1
102 if (a != 0) { }
103
104 // CHECK: icmp ne i64 -1, {{.*}}
105 if (0 != a) { }
106
107 // CHECK: icmp eq i64 {{.*}}, -1
108 if (a == 0) { }
109
110 // CHECK: icmp eq i64 -1, {{.*}}
111 if (0 == a) { }
112 }
113 }
114
115 namespace ValueInit {
116
117 struct A {
118 int A::*a;
119
120 char c;
121
122 A();
123 };
124
125 // CHECK-LABEL: define void @_ZN9ValueInit1AC2Ev(%"struct.ValueInit::A"* %this) unnamed_addr
126 // CHECK: store i64 -1, i64*
127 // CHECK: ret void
A()128 A::A() : a() {}
129
130 }
131
132 namespace VirtualBases {
133
134 struct A {
135 char c;
136 int A::*i;
137 };
138
139 // CHECK-GLOBAL: @_ZN12VirtualBases1bE = global %"struct.VirtualBases::B" { i32 (...)** null, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
140 struct B : virtual A { };
141 B b;
142
143 // CHECK-GLOBAL: @_ZN12VirtualBases1cE = global %"struct.VirtualBases::C" { i32 (...)** null, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
144 struct C : virtual A { int A::*i; };
145 C c;
146
147 // CHECK-GLOBAL: @_ZN12VirtualBases1dE = global %"struct.VirtualBases::D" { %"struct.VirtualBases::C.base" { i32 (...)** null, i64 -1 }, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8
148 struct D : C { int A::*i; };
149 D d;
150
151 }
152
153 namespace Test1 {
154
155 // Don't crash when A contains a bit-field.
156 struct A {
157 int A::* a;
158 int b : 10;
159 };
160 A a;
161
162 }
163
164 namespace BoolPtrToMember {
165 struct X {
166 bool member;
167 };
168
169 // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b
f(X & x,bool X::* member)170 bool &f(X &x, bool X::*member) {
171 // CHECK: {{bitcast.* to i8\*}}
172 // CHECK-NEXT: getelementptr inbounds i8, i8*
173 // CHECK-NEXT: ret i8*
174 return x.*member;
175 }
176 }
177
178 namespace PR8507 {
179
180 struct S;
f(S * p,double S::* pm)181 void f(S* p, double S::*pm) {
182 if (0 < p->*pm) {
183 }
184 }
185
186 }
187
188 namespace test4 {
189 struct A { int A_i; };
190 struct B : virtual A { int A::*B_p; };
191 struct C : virtual B { int *C_p; };
192 struct D : C { int *D_p; };
193
194 // CHECK-GLOBAL: @_ZN5test41dE = global %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.test4::B.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8
195 D d;
196 }
197
198 namespace PR11487 {
199 union U
200 {
201 int U::* mptr;
202 char x[16];
203 } x;
204 // CHECK-GLOBAL: @_ZN7PR114871xE = global %"union.PR11487::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
205
206 }
207
208 namespace PR13097 {
209 struct X { int x; X(const X&); };
210 struct A {
211 int qq;
212 X x;
213 };
214 A f();
g()215 X g() { return f().*&A::x; }
216 // CHECK-LABEL: define void @_ZN7PR130971gEv
217 // CHECK: call void @_ZN7PR130971fEv
218 // CHECK-NOT: memcpy
219 // CHECK: call void @_ZN7PR130971XC1ERKS0_
220 }
221
222 namespace PR21089 {
223 struct A {
224 bool : 1;
225 int A::*x;
226 bool y;
227 A();
228 };
229 struct B : A {
230 };
231 B b;
232 // CHECK-GLOBAL: @_ZN7PR210891bE = global %"struct.PR21089::B" { %"struct.PR21089::A.base" <{ i8 0, [7 x i8] zeroinitializer, i64 -1, i8 0 }>, [7 x i8] zeroinitializer }, align 8
233 }
234
235 namespace PR21282 {
236 union U {
237 int U::*x;
238 long y[2];
239 };
240 U u;
241 // CHECK-GLOBAL: @_ZN7PR212821uE = global %"union.PR21282::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
242 }
243
244 namespace FlexibleArrayMember {
245 struct S {
246 int S::*x[];
247 };
248 S s;
249 // CHECK-GLOBAL: @_ZN19FlexibleArrayMember1sE = global %"struct.FlexibleArrayMember::S" zeroinitializer, align 8
250 }
251
252 namespace IndirectPDM {
253 union U {
254 union {
255 int U::*m;
256 };
257 };
258 U u;
259 // CHECK-GLOBAL: @_ZN11IndirectPDM1uE = global %"union.IndirectPDM::U" { %union.anon { i64 -1 } }, align 8
260 }
261