arm.cpp revision 93c332a8ba2c193c435b293966d343dab15f555b
1// 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
2
3// 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
8typedef typeof(sizeof(int)) size_t;
9
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
23// Checked at end of file.
24bar baz;
25
26// 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
47  // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* %this, i32 %i) unnamed_addr
48  // 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
57  // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* %this) unnamed_addr
58  // 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
98  // 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)
120    // CHECK: [[OR:%.*]] = or i1
121    // CHECK: [[SZ:%.*]] = select i1 [[OR]]
122    // 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*
139    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
140    // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
141    // 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*
211    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
212    // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
213    // 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
246// <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
286namespace 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 @llvm.eh.resume(
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 @llvm.eh.resume(
353  }
354}
355
356  // 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
363
364// CHECK: @_GLOBAL__D_a()
365// CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz)
366