Clang Project

clang_source_code/test/CodeGenCXX/arm.cpp
1// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -std=gnu++98 -o - -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
2// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios6.0 -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -std=gnu++11 -o - -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
3
4// CHECK: @_ZZN5test74testEvE1x = internal global i32 0, align 4
5// CHECK: @_ZGVZN5test74testEvE1x = internal global i32 0
6// CHECK: @_ZZN5test84testEvE1x = internal global [[TEST8A:.*]] zeroinitializer, align 1
7// CHECK: @_ZGVZN5test84testEvE1x = internal global i32 0
8
9typedef typeof(sizeof(int)) size_t;
10
11class foo {
12public:
13    foo();
14    virtual ~foo();
15};
16
17class bar : public foo {
18public:
19 bar();
20};
21
22// The global dtor needs the right calling conv with -fno-use-cxa-atexit
23// rdar://7817590
24bar baz;
25
26// PR9593
27// Make sure atexit(3) is used for global dtors.
28
29// CHECK:      call [[BAR:%.*]]* @_ZN3barC1Ev(
30// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_baz)
31
32// CHECK-NOT: @_GLOBAL__D_a()
33// CHECK-LABEL: define internal void @__dtor_baz()
34// CHECK: call [[BAR]]* @_ZN3barD1Ev([[BAR]]* @baz)
35
36// Destructors and constructors must return this.
37namespace test1 {
38  void foo();
39
40  struct A {
41    A(int i) { foo(); }
42    ~A() { foo(); }
43    void bar() { foo(); }
44  };
45
46  // CHECK-LABEL: define void @_ZN5test14testEv()
47  void test() {
48    // CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1
49    // CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10)
50    // CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]])
51    // CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]])
52    // CHECK: ret void
53    A a = 10;
54    a.bar();
55  }
56
57  // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* returned %this, i32 %i) unnamed_addr
58  // CHECK:   [[THIS:%.*]] = alloca [[A]]*, align 4
59  // CHECK:   store [[A]]* {{.*}}, [[A]]** [[THIS]]
60  // CHECK:   [[THIS1:%.*]] = load [[A]]*, [[A]]** [[THIS]]
61  // CHECK:   {{%.*}} = call [[A]]* @_ZN5test11AC2Ei(
62  // CHECK:   ret [[A]]* [[THIS1]]
63
64  // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* returned %this) unnamed_addr
65  // CHECK:   [[THIS:%.*]] = alloca [[A]]*, align 4
66  // CHECK:   store [[A]]* {{.*}}, [[A]]** [[THIS]]
67  // CHECK:   [[THIS1:%.*]] = load [[A]]*, [[A]]** [[THIS]]
68  // CHECK:   {{%.*}} = call [[A]]* @_ZN5test11AD2Ev(
69  // CHECK:   ret [[A]]* [[THIS1]]
70}
71
72// Awkward virtual cases.
73namespace test2 {
74  void foo();
75
76  struct A {
77    int x;
78
79    A(int);
80    virtual ~A() { foo(); }
81  };
82
83  struct B {
84    int y;
85    int z;
86
87    B(int);
88    virtual ~B() { foo(); }
89  };
90
91  struct C : A, virtual B {
92    int q;
93
94    C(int i) : A(i), B(i) { foo(); }
95    ~C() { foo(); }
96  };
97
98  void test() {
99    C c = 10;
100  }
101
102  // Tests at eof
103}
104
105namespace test3 {
106  struct A {
107    int x;
108    ~A();
109  };
110
111  void a() {
112    // CHECK-LABEL: define void @_ZN5test31aEv()
113    // CHECK: call i8* @_Znam(i32 48)
114    // CHECK: store i32 4
115    // CHECK: store i32 10
116    A *x = new A[10];
117  }
118
119  void b(int n) {
120    // CHECK-LABEL: define void @_ZN5test31bEi(
121    // CHECK: [[N:%.*]] = load i32, i32*
122    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
123    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
124    // CHECK: [[OR:%.*]] = or i1
125    // CHECK: [[SZ:%.*]] = select i1 [[OR]]
126    // CHECK: call i8* @_Znam(i32 [[SZ]])
127    // CHECK: store i32 4
128    // CHECK: store i32 [[N]]
129    A *x = new A[n];
130  }
131
132  void c() {
133    // CHECK-LABEL: define void @_ZN5test31cEv()
134    // CHECK: call  i8* @_Znam(i32 808)
135    // CHECK: store i32 4
136    // CHECK: store i32 200
137    A (*x)[20] = new A[10][20];
138  }
139
140  void d(int n) {
141    // CHECK-LABEL: define void @_ZN5test31dEi(
142    // CHECK: [[N:%.*]] = load i32, i32*
143    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
144    // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
145    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
146    // CHECK: [[SZ:%.*]] = select
147    // CHECK: call i8* @_Znam(i32 [[SZ]])
148    // CHECK: store i32 4
149    // CHECK: store i32 [[NE]]
150    A (*x)[20] = new A[n][20];
151  }
152
153  void e(A *x) {
154    // CHECK-LABEL: define void @_ZN5test31eEPNS_1AE(
155    // CHECK: icmp eq {{.*}}, null
156    // CHECK: getelementptr {{.*}}, i32 -8
157    // CHECK: getelementptr {{.*}}, i32 4
158    // CHECK: bitcast {{.*}} to i32*
159    // CHECK: load
160    // CHECK98: invoke {{.*}} @_ZN5test31AD1Ev
161    // CHECK11: call {{.*}} @_ZN5test31AD1Ev
162    // CHECK: call void @_ZdaPv
163    delete [] x;
164  }
165
166  void f(A (*x)[20]) {
167    // CHECK-LABEL: define void @_ZN5test31fEPA20_NS_1AE(
168    // CHECK: icmp eq {{.*}}, null
169    // CHECK: getelementptr {{.*}}, i32 -8
170    // CHECK: getelementptr {{.*}}, i32 4
171    // CHECK: bitcast {{.*}} to i32*
172    // CHECK: load
173    // CHECK98: invoke {{.*}} @_ZN5test31AD1Ev
174    // CHECK11: call {{.*}} @_ZN5test31AD1Ev
175    // CHECK: call void @_ZdaPv
176    delete [] x;
177  }
178}
179
180namespace test4 {
181  struct A {
182    int x;
183    void operator delete[](void *, size_t sz);
184  };
185
186  void a() {
187    // CHECK-LABEL: define void @_ZN5test41aEv()
188    // CHECK: call i8* @_Znam(i32 48)
189    // CHECK: store i32 4
190    // CHECK: store i32 10
191    A *x = new A[10];
192  }
193
194  void b(int n) {
195    // CHECK-LABEL: define void @_ZN5test41bEi(
196    // CHECK: [[N:%.*]] = load i32, i32*
197    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
198    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
199    // CHECK: [[SZ:%.*]] = select
200    // CHECK: call i8* @_Znam(i32 [[SZ]])
201    // CHECK: store i32 4
202    // CHECK: store i32 [[N]]
203    A *x = new A[n];
204  }
205
206  void c() {
207    // CHECK-LABEL: define void @_ZN5test41cEv()
208    // CHECK: call  i8* @_Znam(i32 808)
209    // CHECK: store i32 4
210    // CHECK: store i32 200
211    A (*x)[20] = new A[10][20];
212  }
213
214  void d(int n) {
215    // CHECK-LABEL: define void @_ZN5test41dEi(
216    // CHECK: [[N:%.*]] = load i32, i32*
217    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
218    // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
219    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
220    // CHECK: [[SZ:%.*]] = select
221    // CHECK: call i8* @_Znam(i32 [[SZ]])
222    // CHECK: store i32 4
223    // CHECK: store i32 [[NE]]
224    A (*x)[20] = new A[n][20];
225  }
226
227  void e(A *x) {
228    // CHECK-LABEL: define void @_ZN5test41eEPNS_1AE(
229    // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i32 -8
230    // CHECK: getelementptr inbounds {{.*}}, i32 4
231    // CHECK: bitcast
232    // CHECK: [[T0:%.*]] = load i32, 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  void f(A (*x)[20]) {
240    // CHECK-LABEL: define void @_ZN5test41fEPA20_NS_1AE(
241    // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i32 -8
242    // CHECK: getelementptr inbounds {{.*}}, i32 4
243    // CHECK: bitcast
244    // CHECK: [[T0:%.*]] = load i32, i32*
245    // CHECK: [[T1:%.*]] = mul i32 4, [[T0]]
246    // CHECK: [[T2:%.*]] = add i32 [[T1]], 8
247    // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]])
248    delete [] x;
249  }
250}
251
252// <rdar://problem/8386802>: don't crash
253namespace test5 {
254  struct A {
255    ~A();
256  };
257
258  // CHECK-LABEL: define void @_ZN5test54testEPNS_1AE
259  void test(A *a) {
260    // CHECK:      [[PTR:%.*]] = alloca [[A:%.*]]*, align 4
261    // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4
262    // CHECK-NEXT: [[TMP:%.*]] = load [[A]]*, [[A]]** [[PTR]], align 4
263    // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]])
264    // CHECK-NEXT: ret void
265    a->~A();
266  }
267}
268
269namespace test6 {
270  struct A {
271    virtual ~A();
272  };
273
274  // CHECK-LABEL: define void @_ZN5test64testEPNS_1AE
275  void test(A *a) {
276    // CHECK:      [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4
277    // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4
278    // CHECK-NEXT: [[V:%.*]] = load [[A]]*, [[A]]** [[AVAR]], align 4
279    // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null
280    // CHECK-NEXT: br i1 [[ISNULL]]
281    // CHECK:      [[T0:%.*]] = bitcast [[A]]* [[V]] to void ([[A]]*)***
282    // CHECK-NEXT: [[T1:%.*]] = load void ([[A]]*)**, void ([[A]]*)*** [[T0]]
283    // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds void ([[A]]*)*, void ([[A]]*)** [[T1]], i64 1
284    // CHECK-NEXT: [[T3:%.*]] = load void ([[A]]*)*, void ([[A]]*)** [[T2]]
285    // CHECK-NEXT: call void [[T3]]([[A]]* [[V]])
286    // CHECK-NEXT: br label
287    // CHECK:      ret void
288    delete a;
289  }
290}
291
292namespace test7 {
293  int foo();
294
295  // Static and guard tested at top of file
296
297  // CHECK-LABEL: define void @_ZN5test74testEv() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
298  void test() {
299    // CHECK:      [[T0:%.*]] = load atomic i8, i8* bitcast (i32* @_ZGVZN5test74testEvE1x to i8*) acquire, align 4
300    // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1
301    // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0
302    // CHECK-NEXT: br i1 [[T2]]
303    //   -> fallthrough, end
304    // CHECK:      [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x)
305    // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
306    // CHECK-NEXT: br i1 [[T4]]
307    //   -> fallthrough, end
308    // CHECK:      [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv()
309    // CHECK:      store i32 [[INIT]], i32* @_ZZN5test74testEvE1x, align 4
310    // CHECK-NEXT: call void @__cxa_guard_release(i32* @_ZGVZN5test74testEvE1x)
311    // CHECK-NEXT: br label
312    //   -> end
313    // end:
314    // CHECK:      ret void
315    static int x = foo();
316
317    // CHECK:      landingpad { i8*, i32 }
318    // CHECK-NEXT:   cleanup
319    // CHECK:      call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
320    // CHECK:      resume { i8*, i32 }
321  }
322}
323
324namespace test8 {
325  struct A {
326    A();
327    ~A();
328  };
329
330  // Static and guard tested at top of file
331
332  // CHECK-LABEL: define void @_ZN5test84testEv() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
333  void test() {
334    // CHECK:      [[T0:%.*]] = load atomic i8, i8* bitcast (i32* @_ZGVZN5test84testEvE1x to i8*) acquire, align 4
335    // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1
336    // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0
337    // CHECK-NEXT: br i1 [[T2]]
338    //   -> fallthrough, end
339    // CHECK:      [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x)
340    // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
341    // CHECK-NEXT: br i1 [[T4]]
342    //   -> fallthrough, end
343    // CHECK:      [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x)
344
345    // FIXME: Here we register a global destructor that
346    // unconditionally calls the destructor.  That's what we've always
347    // done for -fno-use-cxa-atexit here, but that's really not
348    // semantically correct at all.
349
350    // CHECK:      call void @__cxa_guard_release(i32* @_ZGVZN5test84testEvE1x)
351    // CHECK-NEXT: br label
352    //   -> end
353    // end:
354    // CHECK:      ret void
355    static A x;
356
357    // CHECK:      landingpad { i8*, i32 }
358    // CHECK-NEXT:   cleanup
359    // CHECK:      call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
360    // CHECK:      resume { i8*, i32 }
361  }
362}
363
364//   rdar://12836470
365// Use a larger-than-mandated array cookie when allocating an
366// array whose type is overaligned.
367namespace test9 {
368  class __attribute__((aligned(16))) A {
369    float data[4];
370  public:
371    A();
372    ~A();
373  };
374
375  A *testNew(unsigned n) {
376    return new A[n];
377  }
378// CHECK:    define [[TEST9:%.*]]* @_ZN5test97testNewEj(i32
379// CHECK:      [[N_VAR:%.*]] = alloca i32, align 4
380// CHECK:      [[N:%.*]] = load i32, i32* [[N_VAR]], align 4
381// CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 16)
382// CHECK-NEXT: [[O0:%.*]] = extractvalue { i32, i1 } [[T0]], 1
383// CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 0
384// CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 16)
385// CHECK-NEXT: [[O1:%.*]] = extractvalue { i32, i1 } [[T2]], 1
386// CHECK-NEXT: [[OVERFLOW:%.*]] = or i1 [[O0]], [[O1]]
387// CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
388// CHECK-NEXT: [[T4:%.*]] = select i1 [[OVERFLOW]], i32 -1, i32 [[T3]]
389// CHECK-NEXT: [[ALLOC:%.*]] = call i8* @_Znam(i32 [[T4]])
390// CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[ALLOC]] to i32*
391// CHECK-NEXT: store i32 16, i32* [[T0]]
392// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i32, i32* [[T0]], i32 1
393// CHECK-NEXT: store i32 [[N]], i32* [[T1]]
394// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8, i8* [[ALLOC]], i32 16
395// CHECK-NEXT: bitcast i8* [[T0]] to [[TEST9]]*
396//   Array allocation follows.
397
398  void testDelete(A *array) {
399    delete[] array;
400  }
401// CHECK-LABEL:    define void @_ZN5test910testDeleteEPNS_1AE(
402// CHECK:      [[BEGIN:%.*]] = load [[TEST9]]*, [[TEST9]]**
403// CHECK-NEXT: [[T0:%.*]] = icmp eq [[TEST9]]* [[BEGIN]], null
404// CHECK-NEXT: br i1 [[T0]],
405// CHECK:      [[T0:%.*]] = bitcast [[TEST9]]* [[BEGIN]] to i8*
406// CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8, i8* [[T0]], i32 -16
407// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8, i8* [[ALLOC]], i32 4
408// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
409// CHECK-NEXT: [[N:%.*]] = load i32, i32* [[T1]]
410// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[TEST9]], [[TEST9]]* [[BEGIN]], i32 [[N]]
411// CHECK-NEXT: [[T0:%.*]] = icmp eq [[TEST9]]* [[BEGIN]], [[END]]
412// CHECK-NEXT: br i1 [[T0]],
413//   Array deallocation follows.
414}
415
416  // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev(
417  // CHECK:   call [[C]]* @_ZN5test21CD1Ev(
418  // CHECK:   ret [[C]]* undef
419
420  // CHECK-LABEL: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev(
421  // CHECK:   call void @_ZN5test21CD0Ev(
422  // CHECK:   ret void
423