arm.cpp revision 1e7fe751466ea82665fd21e9162fd7cc9c5f412d
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
3typedef typeof(sizeof(int)) size_t;
4
5class foo {
6public:
7    foo();
8    virtual ~foo();
9};
10
11class bar : public foo {
12public:
13	bar();
14};
15
16// The global dtor needs the right calling conv with -fno-use-cxa-atexit
17// rdar://7817590
18// Checked at end of file.
19bar baz;
20
21// Destructors and constructors must return this.
22namespace test1 {
23  void foo();
24
25  struct A {
26    A(int i) { foo(); }
27    ~A() { foo(); }
28    void bar() { foo(); }
29  };
30
31  // CHECK: define void @_ZN5test14testEv()
32  void test() {
33    // CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1
34    // CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10)
35    // CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]])
36    // CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]])
37    // CHECK: ret void
38    A a = 10;
39    a.bar();
40  }
41
42  // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]*
43  // CHECK:   [[RET:%.*]] = alloca [[A]]*, align 4
44  // CHECK:   [[THIS:%.*]] = alloca [[A]]*, align 4
45  // CHECK:   store [[A]]* {{.*}}, [[A]]** [[THIS]]
46  // CHECK:   [[THIS1:%.*]] = load [[A]]** [[THIS]]
47  // CHECK:   store [[A]]* [[THIS1]], [[A]]** [[RET]]
48  // CHECK:   call [[A]]* @_ZN5test11AC2Ei(
49  // CHECK:   [[THIS2:%.*]] = load [[A]]** [[RET]]
50  // CHECK:   ret [[A]]* [[THIS2]]
51
52  // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]*
53  // CHECK:   [[RET:%.*]] = alloca [[A]]*, align 4
54  // CHECK:   [[THIS:%.*]] = alloca [[A]]*, align 4
55  // CHECK:   store [[A]]* {{.*}}, [[A]]** [[THIS]]
56  // CHECK:   [[THIS1:%.*]] = load [[A]]** [[THIS]]
57  // CHECK:   store [[A]]* [[THIS1]], [[A]]** [[RET]]
58  // CHECK:   call [[A]]* @_ZN5test11AD2Ev(
59  // CHECK:   [[THIS2:%.*]] = load [[A]]** [[RET]]
60  // CHECK:   ret [[A]]* [[THIS2]]
61}
62
63// Awkward virtual cases.
64namespace test2 {
65  void foo();
66
67  struct A {
68    int x;
69
70    A(int);
71    virtual ~A() { foo(); }
72  };
73
74  struct B {
75    int y;
76    int z;
77
78    B(int);
79    virtual ~B() { foo(); }
80  };
81
82  struct C : A, virtual B {
83    int q;
84
85    C(int i) : A(i), B(i) { foo(); }
86    ~C() { foo(); }
87  };
88
89  void test() {
90    C c = 10;
91  }
92
93  // Tests at eof
94}
95
96namespace test3 {
97  struct A {
98    int x;
99    ~A();
100  };
101
102  void a() {
103    // CHECK: define void @_ZN5test31aEv()
104    // CHECK: call noalias i8* @_Znam(i32 48)
105    // CHECK: store i32 4
106    // CHECK: store i32 10
107    A *x = new A[10];
108  }
109
110  void b(int n) {
111    // CHECK: define void @_ZN5test31bEi(
112    // CHECK: [[N:%.*]] = load i32*
113    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
114    // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
115    // CHECK: [[SZ:%.*]] = select
116    // 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*
133    // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
134    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
135    // 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*
205    // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
206    // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
207    // 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
240  // CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev(
241  // CHECK:   call [[C]]* @_ZN5test21CD1Ev(
242  // CHECK:   ret [[C]]* undef
243
244  // CHECK: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev(
245  // CHECK:   call void @_ZN5test21CD0Ev(
246  // CHECK:   ret void
247
248// CHECK: @_GLOBAL__D_a()
249// CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz)
250