blob: f56b1552ce6dc0c65f07dcc091b85cfd171bd010 [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: [[RET:%.*]] = alloca [[A]]*, align 4
49 // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
50 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
51 // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]]
52 // CHECK: store [[A]]* [[THIS1]], [[A]]** [[RET]]
53 // CHECK: call [[A]]* @_ZN5test11AC2Ei(
54 // CHECK: [[THIS2:%.*]] = load [[A]]** [[RET]]
55 // CHECK: ret [[A]]* [[THIS2]]
56
Rafael Espindola0691a5c2011-01-25 19:10:24 +000057 // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* %this) unnamed_addr
John McCall4c40d982010-08-31 07:33:07 +000058 // CHECK: [[RET:%.*]] = alloca [[A]]*, align 4
59 // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
60 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
61 // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]]
62 // CHECK: store [[A]]* [[THIS1]], [[A]]** [[RET]]
63 // CHECK: call [[A]]* @_ZN5test11AD2Ev(
64 // CHECK: [[THIS2:%.*]] = load [[A]]** [[RET]]
65 // CHECK: ret [[A]]* [[THIS2]]
66}
67
68// Awkward virtual cases.
69namespace test2 {
70 void foo();
71
72 struct A {
73 int x;
74
75 A(int);
76 virtual ~A() { foo(); }
77 };
78
79 struct B {
80 int y;
81 int z;
82
83 B(int);
84 virtual ~B() { foo(); }
85 };
86
87 struct C : A, virtual B {
88 int q;
89
90 C(int i) : A(i), B(i) { foo(); }
91 ~C() { foo(); }
92 };
93
94 void test() {
95 C c = 10;
96 }
97
John McCall1e7fe752010-09-02 09:58:18 +000098 // Tests at eof
99}
100
101namespace test3 {
102 struct A {
103 int x;
104 ~A();
105 };
106
107 void a() {
108 // CHECK: define void @_ZN5test31aEv()
109 // CHECK: call noalias i8* @_Znam(i32 48)
110 // CHECK: store i32 4
111 // CHECK: store i32 10
112 A *x = new A[10];
113 }
114
115 void b(int n) {
116 // CHECK: define void @_ZN5test31bEi(
117 // CHECK: [[N:%.*]] = load i32*
118 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
119 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
Eli Friedman5536daa2011-04-09 19:54:33 +0000120 // CHECK: [[OR:%.*]] = or i1
121 // CHECK: [[SZ:%.*]] = select i1 [[OR]]
John McCall1e7fe752010-09-02 09:58:18 +0000122 // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
123 // CHECK: store i32 4
124 // CHECK: store i32 [[N]]
125 A *x = new A[n];
126 }
127
128 void c() {
129 // CHECK: define void @_ZN5test31cEv()
130 // CHECK: call noalias i8* @_Znam(i32 808)
131 // CHECK: store i32 4
132 // CHECK: store i32 200
133 A (*x)[20] = new A[10][20];
134 }
135
136 void d(int n) {
137 // CHECK: define void @_ZN5test31dEi(
138 // CHECK: [[N:%.*]] = load i32*
John McCall1e7fe752010-09-02 09:58:18 +0000139 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
John McCall7d166272011-05-15 07:14:44 +0000140 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
John McCall1e7fe752010-09-02 09:58:18 +0000141 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
142 // CHECK: [[SZ:%.*]] = select
143 // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
144 // CHECK: store i32 4
145 // CHECK: store i32 [[NE]]
146 A (*x)[20] = new A[n][20];
147 }
148
149 void e(A *x) {
150 // CHECK: define void @_ZN5test31eEPNS_1AE(
151 // CHECK: icmp eq {{.*}}, null
152 // CHECK: getelementptr {{.*}}, i64 -8
153 // CHECK: getelementptr {{.*}}, i64 4
154 // CHECK: bitcast {{.*}} to i32*
155 // CHECK: load
156 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev
157 // CHECK: call void @_ZdaPv
158 delete [] x;
159 }
160
161 void f(A (*x)[20]) {
162 // CHECK: define void @_ZN5test31fEPA20_NS_1AE(
163 // CHECK: icmp eq {{.*}}, null
164 // CHECK: getelementptr {{.*}}, i64 -8
165 // CHECK: getelementptr {{.*}}, i64 4
166 // CHECK: bitcast {{.*}} to i32*
167 // CHECK: load
168 // CHECK: invoke {{.*}} @_ZN5test31AD1Ev
169 // CHECK: call void @_ZdaPv
170 delete [] x;
171 }
172}
173
174namespace test4 {
175 struct A {
176 int x;
177 void operator delete[](void *, size_t sz);
178 };
179
180 void a() {
181 // CHECK: define void @_ZN5test41aEv()
182 // CHECK: call noalias i8* @_Znam(i32 48)
183 // CHECK: store i32 4
184 // CHECK: store i32 10
185 A *x = new A[10];
186 }
187
188 void b(int n) {
189 // CHECK: define void @_ZN5test41bEi(
190 // CHECK: [[N:%.*]] = load i32*
191 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
192 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
193 // CHECK: [[SZ:%.*]] = select
194 // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
195 // CHECK: store i32 4
196 // CHECK: store i32 [[N]]
197 A *x = new A[n];
198 }
199
200 void c() {
201 // CHECK: define void @_ZN5test41cEv()
202 // CHECK: call noalias i8* @_Znam(i32 808)
203 // CHECK: store i32 4
204 // CHECK: store i32 200
205 A (*x)[20] = new A[10][20];
206 }
207
208 void d(int n) {
209 // CHECK: define void @_ZN5test41dEi(
210 // CHECK: [[N:%.*]] = load i32*
John McCall1e7fe752010-09-02 09:58:18 +0000211 // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
John McCall7d166272011-05-15 07:14:44 +0000212 // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
John McCall1e7fe752010-09-02 09:58:18 +0000213 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
214 // CHECK: [[SZ:%.*]] = select
215 // CHECK: call noalias i8* @_Znam(i32 [[SZ]])
216 // CHECK: store i32 4
217 // CHECK: store i32 [[NE]]
218 A (*x)[20] = new A[n][20];
219 }
220
221 void e(A *x) {
222 // CHECK: define void @_ZN5test41eEPNS_1AE(
223 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8
224 // CHECK: getelementptr inbounds {{.*}}, i64 4
225 // CHECK: bitcast
226 // CHECK: [[T0:%.*]] = load i32*
227 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]
228 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8
229 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]])
230 delete [] x;
231 }
232
233 void f(A (*x)[20]) {
234 // CHECK: define void @_ZN5test41fEPA20_NS_1AE(
235 // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8
236 // CHECK: getelementptr inbounds {{.*}}, i64 4
237 // CHECK: bitcast
238 // CHECK: [[T0:%.*]] = load i32*
239 // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]
240 // CHECK: [[T2:%.*]] = add i32 [[T1]], 8
241 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]])
242 delete [] x;
243 }
244}
245
John McCallfc400282010-09-03 01:26:39 +0000246// <rdar://problem/8386802>: don't crash
247namespace test5 {
248 struct A {
249 ~A();
250 };
251
252 // CHECK: define void @_ZN5test54testEPNS_1AE
253 void test(A *a) {
254 // CHECK: [[PTR:%.*]] = alloca [[A:%.*]]*, align 4
255 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4
256 // CHECK-NEXT: [[TMP:%.*]] = load [[A]]** [[PTR]], align 4
257 // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]])
258 // CHECK-NEXT: ret void
259 a->~A();
260 }
261}
262
263namespace test6 {
264 struct A {
265 virtual ~A();
266 };
267
268 // CHECK: define void @_ZN5test64testEPNS_1AE
269 void test(A *a) {
270 // CHECK: [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4
271 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4
272 // CHECK-NEXT: [[V:%.*]] = load [[A]]** [[AVAR]], align 4
273 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null
274 // CHECK-NEXT: br i1 [[ISNULL]]
275 // CHECK: [[T0:%.*]] = bitcast [[A]]* [[V]] to [[A]]* ([[A]]*)***
276 // CHECK-NEXT: [[T1:%.*]] = load [[A]]* ([[A]]*)*** [[T0]]
277 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* ([[A]]*)** [[T1]], i64 1
278 // CHECK-NEXT: [[T3:%.*]] = load [[A]]* ([[A]]*)** [[T2]]
279 // CHECK-NEXT: call [[A]]* [[T3]]([[A]]* [[V]])
280 // CHECK-NEXT: br label
281 // CHECK: ret void
282 delete a;
283 }
284}
285
John McCall5cd91b52010-09-08 01:44:27 +0000286namespace test7 {
287 int foo();
288
289 // Static and guard tested at top of file
290
291 // CHECK: define void @_ZN5test74testEv()
292 void test() {
293 // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test74testEvE1x
294 // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
295 // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
296 // CHECK-NEXT: br i1 [[T2]]
297 // -> fallthrough, end
298 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x)
299 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
300 // CHECK-NEXT: br i1 [[T4]]
301 // -> fallthrough, end
302 // CHECK: [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv()
303 // CHECK: store i32 [[INIT]], i32* @_ZZN5test74testEvE1x, align 4
304 // CHECK-NEXT: call void @__cxa_guard_release(i32* @_ZGVZN5test74testEvE1x)
305 // CHECK-NEXT: br label
306 // -> end
307 // end:
308 // CHECK: ret void
309 static int x = foo();
310
311 // CHECK: call i8* @llvm.eh.exception()
312 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
313 // CHECK: call void @_Unwind_Resume_or_Rethrow
314 }
315}
316
317namespace test8 {
318 struct A {
319 A();
320 ~A();
321 };
322
323 // Static and guard tested at top of file
324
325 // CHECK: define void @_ZN5test84testEv()
326 void test() {
327 // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test84testEvE1x
328 // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
329 // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
330 // CHECK-NEXT: br i1 [[T2]]
331 // -> fallthrough, end
332 // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x)
333 // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
334 // CHECK-NEXT: br i1 [[T4]]
335 // -> fallthrough, end
336 // CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x)
337
338 // FIXME: Here we register a global destructor that
339 // unconditionally calls the destructor. That's what we've always
340 // done for -fno-use-cxa-atexit here, but that's really not
341 // semantically correct at all.
342
343 // CHECK: call void @__cxa_guard_release(i32* @_ZGVZN5test84testEvE1x)
344 // CHECK-NEXT: br label
345 // -> end
346 // end:
347 // CHECK: ret void
348 static A x;
349
350 // CHECK: call i8* @llvm.eh.exception()
351 // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
352 // CHECK: call void @_Unwind_Resume_or_Rethrow
353 }
354}
355
John McCall4c40d982010-08-31 07:33:07 +0000356 // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev(
357 // CHECK: call [[C]]* @_ZN5test21CD1Ev(
358 // CHECK: ret [[C]]* undef
359
360 // CHECK: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev(
361 // CHECK: call void @_ZN5test21CD0Ev(
362 // CHECK: ret void
John McCall4c40d982010-08-31 07:33:07 +0000363
Chris Lattnerc9a85f92010-04-26 20:35:54 +0000364// CHECK: @_GLOBAL__D_a()
John McCall4c40d982010-08-31 07:33:07 +0000365// CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz)