blob: 0a4754b815a557cf11315b3fdf60dadf672f01e1 [file] [log] [blame]
John McCallae180962010-09-02 10:15:05 +00001// RUN: %clang_cc1 %s -triple=thumbv7-apple-darwin3.0.0-iphoneos -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - -fexceptions | FileCheck %s
John McCall1e7fe752010-09-02 09:58:18 +00002
John McCall5cd91b52010-09-08 01:44:27 +00003// CHECK: @_ZZN5test74testEvE1x = internal global i32 0, align 4
4// CHECK: @_ZGVZN5test74testEvE1x = internal global i32 0
5// CHECK: @_ZZN5test84testEvE1x = internal global [[TEST8A:.*]] zeroinitializer, align 1
6// CHECK: @_ZGVZN5test84testEvE1x = internal global i32 0
7
John McCall1e7fe752010-09-02 09:58:18 +00008typedef typeof(sizeof(int)) size_t;
Chris Lattnerc9a85f92010-04-26 20:35:54 +00009
10class foo {
11public:
12 foo();
13 virtual ~foo();
14};
15
16class bar : public foo {
17public:
18 bar();
19};
20
21// The global dtor needs the right calling conv with -fno-use-cxa-atexit
22// rdar://7817590
John McCall4c40d982010-08-31 07:33:07 +000023// Checked at end of file.
Chris Lattnerc9a85f92010-04-26 20:35:54 +000024bar baz;
25
John McCall4c40d982010-08-31 07:33:07 +000026// Destructors and constructors must return this.
27namespace test1 {
28 void foo();
29
30 struct A {
31 A(int i) { foo(); }
32 ~A() { foo(); }
33 void bar() { foo(); }
34 };
35
36 // CHECK: define void @_ZN5test14testEv()
37 void test() {
38 // CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1
39 // CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10)
40 // CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]])
41 // CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]])
42 // CHECK: ret void
43 A a = 10;
44 a.bar();
45 }
46
Rafael Espindola0691a5c2011-01-25 19:10:24 +000047 // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* %this, i32 %i) unnamed_addr
John McCall4c40d982010-08-31 07:33:07 +000048 // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
49 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
50 // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]]
John McCall4c40d982010-08-31 07:33:07 +000051 // CHECK: call [[A]]* @_ZN5test11AC2Ei(
John McCallf48f7962012-01-29 02:35:02 +000052 // CHECK: ret [[A]]* [[THIS1]]
John McCall4c40d982010-08-31 07:33:07 +000053
Rafael Espindola0691a5c2011-01-25 19:10:24 +000054 // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* %this) unnamed_addr
John McCall4c40d982010-08-31 07:33:07 +000055 // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
56 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
57 // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]]
John McCall4c40d982010-08-31 07:33:07 +000058 // CHECK: call [[A]]* @_ZN5test11AD2Ev(
John McCallf48f7962012-01-29 02:35:02 +000059 // CHECK: ret [[A]]* [[THIS1]]
John McCall4c40d982010-08-31 07:33:07 +000060}
61
62// Awkward virtual cases.
63namespace test2 {
64 void foo();
65
66 struct A {
67 int x;
68
69 A(int);
70 virtual ~A() { foo(); }
71 };
72
73 struct B {
74 int y;
75 int z;
76
77 B(int);
78 virtual ~B() { foo(); }
79 };
80
81 struct C : A, virtual B {
82 int q;
83
84 C(int i) : A(i), B(i) { foo(); }
85 ~C() { foo(); }
86 };
87
88 void test() {
89 C c = 10;
90 }
91
John McCall1e7fe752010-09-02 09:58:18 +000092 // Tests at eof
93}
94
95namespace test3 {
96 struct A {
97 int x;
98 ~A();
99 };
100
101 void a() {
102 // CHECK: define void @_ZN5test31aEv()
103 // CHECK: call noalias i8* @_Znam(i32 48)
104 // CHECK: store i32 4
105 // CHECK: store i32 10
106 A *x = new A[10];
107 }
108
109 void b(int n) {
110 // CHECK: define void @_ZN5test31bEi(
111 // CHECK: [[N:%.*]] = load i32*
112 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
113 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
Eli Friedman5536daa2011-04-09 19:54:33 +0000114 // CHECK: [[OR:%.*]] = or i1
115 // CHECK: [[SZ:%.*]] = select i1 [[OR]]
John McCall1e7fe752010-09-02 09:58:18 +0000116 // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
117 // CHECK: store i32 4
118 // CHECK: store i32 [[N]]
119 A *x = new A[n];
120 }
121
122 void c() {
123 // CHECK: define void @_ZN5test31cEv()
124 // CHECK: call noalias i8* @_Znam(i32 808)
125 // CHECK: store i32 4
126 // CHECK: store i32 200
127 A (*x)[20] = new A[10][20];
128 }
129
130 void d(int n) {
131 // CHECK: define void @_ZN5test31dEi(
132 // CHECK: [[N:%.*]] = load i32*
John McCall1e7fe752010-09-02 09:58:18 +0000133 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
John McCall7d166272011-05-15 07:14:44 +0000134 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
John McCall1e7fe752010-09-02 09:58:18 +0000135 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
136 // CHECK: [[SZ:%.*]] = select
137 // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
138 // CHECK: store i32 4
139 // CHECK: store i32 [[NE]]
140 A (*x)[20] = new A[n][20];
141 }
142
143 void e(A *x) {
144 // CHECK: define void @_ZN5test31eEPNS_1AE(
145 // CHECK: icmp eq {{.*}}, null
146 // CHECK: getelementptr {{.*}}, i64 -8
147 // CHECK: getelementptr {{.*}}, i64 4
148 // CHECK: bitcast {{.*}} to i32*
149 // CHECK: load
150 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev
151 // CHECK: call void @_ZdaPv
152 delete [] x;
153 }
154
155 void f(A (*x)[20]) {
156 // CHECK: define void @_ZN5test31fEPA20_NS_1AE(
157 // CHECK: icmp eq {{.*}}, null
158 // CHECK: getelementptr {{.*}}, i64 -8
159 // CHECK: getelementptr {{.*}}, i64 4
160 // CHECK: bitcast {{.*}} to i32*
161 // CHECK: load
162 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev
163 // CHECK: call void @_ZdaPv
164 delete [] x;
165 }
166}
167
168namespace test4 {
169 struct A {
170 int x;
171 void operator delete[](void *, size_t sz);
172 };
173
174 void a() {
175 // CHECK: define void @_ZN5test41aEv()
176 // CHECK: call noalias i8* @_Znam(i32 48)
177 // CHECK: store i32 4
178 // CHECK: store i32 10
179 A *x = new A[10];
180 }
181
182 void b(int n) {
183 // CHECK: define void @_ZN5test41bEi(
184 // CHECK: [[N:%.*]] = load i32*
185 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
186 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
187 // CHECK: [[SZ:%.*]] = select
188 // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
189 // CHECK: store i32 4
190 // CHECK: store i32 [[N]]
191 A *x = new A[n];
192 }
193
194 void c() {
195 // CHECK: define void @_ZN5test41cEv()
196 // CHECK: call noalias i8* @_Znam(i32 808)
197 // CHECK: store i32 4
198 // CHECK: store i32 200
199 A (*x)[20] = new A[10][20];
200 }
201
202 void d(int n) {
203 // CHECK: define void @_ZN5test41dEi(
204 // CHECK: [[N:%.*]] = load i32*
John McCall1e7fe752010-09-02 09:58:18 +0000205 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
John McCall7d166272011-05-15 07:14:44 +0000206 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
John McCall1e7fe752010-09-02 09:58:18 +0000207 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
208 // CHECK: [[SZ:%.*]] = select
209 // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
210 // CHECK: store i32 4
211 // CHECK: store i32 [[NE]]
212 A (*x)[20] = new A[n][20];
213 }
214
215 void e(A *x) {
216 // CHECK: define void @_ZN5test41eEPNS_1AE(
217 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8
218 // CHECK: getelementptr inbounds {{.*}}, i64 4
219 // CHECK: bitcast
220 // CHECK: [[T0:%.*]] = load i32*
221 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]
222 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8
223 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]])
224 delete [] x;
225 }
226
227 void f(A (*x)[20]) {
228 // CHECK: define void @_ZN5test41fEPA20_NS_1AE(
229 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8
230 // CHECK: getelementptr inbounds {{.*}}, i64 4
231 // CHECK: bitcast
232 // CHECK: [[T0:%.*]] = load i32*
233 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]
234 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8
235 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]])
236 delete [] x;
237 }
238}
239
John McCallfc400282010-09-03 01:26:39 +0000240// <rdar://problem/8386802>: don't crash
241namespace test5 {
242 struct A {
243 ~A();
244 };
245
246 // CHECK: define void @_ZN5test54testEPNS_1AE
247 void test(A *a) {
248 // CHECK: [[PTR:%.*]] = alloca [[A:%.*]]*, align 4
249 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4
250 // CHECK-NEXT: [[TMP:%.*]] = load [[A]]** [[PTR]], align 4
251 // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]])
252 // CHECK-NEXT: ret void
253 a->~A();
254 }
255}
256
257namespace test6 {
258 struct A {
259 virtual ~A();
260 };
261
262 // CHECK: define void @_ZN5test64testEPNS_1AE
263 void test(A *a) {
264 // CHECK: [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4
265 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4
266 // CHECK-NEXT: [[V:%.*]] = load [[A]]** [[AVAR]], align 4
267 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null
268 // CHECK-NEXT: br i1 [[ISNULL]]
269 // CHECK: [[T0:%.*]] = bitcast [[A]]* [[V]] to [[A]]* ([[A]]*)***
270 // CHECK-NEXT: [[T1:%.*]] = load [[A]]* ([[A]]*)*** [[T0]]
271 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* ([[A]]*)** [[T1]], i64 1
272 // CHECK-NEXT: [[T3:%.*]] = load [[A]]* ([[A]]*)** [[T2]]
273 // CHECK-NEXT: call [[A]]* [[T3]]([[A]]* [[V]])
274 // CHECK-NEXT: br label
275 // CHECK: ret void
276 delete a;
277 }
278}
279
John McCall5cd91b52010-09-08 01:44:27 +0000280namespace test7 {
281 int foo();
282
283 // Static and guard tested at top of file
284
285 // CHECK: define void @_ZN5test74testEv()
286 void test() {
287 // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test74testEvE1x
288 // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
289 // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
290 // CHECK-NEXT: br i1 [[T2]]
291 // -> fallthrough, end
292 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x)
293 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
294 // CHECK-NEXT: br i1 [[T4]]
295 // -> fallthrough, end
296 // CHECK: [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv()
297 // CHECK: store i32 [[INIT]], i32* @_ZZN5test74testEvE1x, align 4
298 // CHECK-NEXT: call void @__cxa_guard_release(i32* @_ZGVZN5test74testEvE1x)
299 // CHECK-NEXT: br label
300 // -> end
301 // end:
302 // CHECK: ret void
303 static int x = foo();
304
Bill Wendling285cfd82011-09-19 20:31:14 +0000305 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
306 // CHECK-NEXT: cleanup
John McCall5cd91b52010-09-08 01:44:27 +0000307 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
Bill Wendling285cfd82011-09-19 20:31:14 +0000308 // CHECK: resume { i8*, i32 }
John McCall5cd91b52010-09-08 01:44:27 +0000309 }
310}
311
312namespace test8 {
313 struct A {
314 A();
315 ~A();
316 };
317
318 // Static and guard tested at top of file
319
320 // CHECK: define void @_ZN5test84testEv()
321 void test() {
322 // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test84testEvE1x
323 // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
324 // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
325 // CHECK-NEXT: br i1 [[T2]]
326 // -> fallthrough, end
327 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x)
328 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
329 // CHECK-NEXT: br i1 [[T4]]
330 // -> fallthrough, end
331 // CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x)
332
333 // FIXME: Here we register a global destructor that
334 // unconditionally calls the destructor. That's what we've always
335 // done for -fno-use-cxa-atexit here, but that's really not
336 // semantically correct at all.
337
338 // CHECK: call void @__cxa_guard_release(i32* @_ZGVZN5test84testEvE1x)
339 // CHECK-NEXT: br label
340 // -> end
341 // end:
342 // CHECK: ret void
343 static A x;
344
Bill Wendling285cfd82011-09-19 20:31:14 +0000345 // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
346 // CHECK-NEXT: cleanup
John McCall5cd91b52010-09-08 01:44:27 +0000347 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
Bill Wendling285cfd82011-09-19 20:31:14 +0000348 // CHECK: resume { i8*, i32 }
John McCall5cd91b52010-09-08 01:44:27 +0000349 }
350}
351
John McCall4c40d982010-08-31 07:33:07 +0000352 // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev(
353 // CHECK: call [[C]]* @_ZN5test21CD1Ev(
354 // CHECK: ret [[C]]* undef
355
356 // CHECK: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev(
357 // CHECK: call void @_ZN5test21CD0Ev(
358 // CHECK: ret void
John McCall4c40d982010-08-31 07:33:07 +0000359
Chris Lattnerc9a85f92010-04-26 20:35:54 +0000360// CHECK: @_GLOBAL__D_a()
John McCall4c40d982010-08-31 07:33:07 +0000361// CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz)