blob: 84d55c8f19071d971c9320263329d66e932a6ef8 [file] [log] [blame]
John McCall7d8647f2010-09-14 07:57:04 +00001// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fexceptions | FileCheck %s
Anders Carlsson8370c582009-12-11 00:32:37 +00002
John McCall7d8647f2010-09-14 07:57:04 +00003typedef typeof(sizeof(0)) size_t;
Anders Carlsson8370c582009-12-11 00:32:37 +00004
John McCall7d8647f2010-09-14 07:57:04 +00005// This just shouldn't crash.
6namespace test0 {
7 struct allocator {
8 allocator();
9 allocator(const allocator&);
10 ~allocator();
11 };
Anders Carlsson8370c582009-12-11 00:32:37 +000012
John McCall7d8647f2010-09-14 07:57:04 +000013 void f();
14 void g(bool b, bool c) {
15 if (b) {
16 if (!c)
17 throw allocator();
18
19 return;
20 }
21 f();
Anders Carlsson8370c582009-12-11 00:32:37 +000022 }
John McCall7d8647f2010-09-14 07:57:04 +000023}
24
25namespace test1 {
26 struct A { A(int); A(int, int); ~A(); void *p; };
27
28 A *a() {
29 // CHECK: define [[A:%.*]]* @_ZN5test11aEv()
30 // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
31 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
32 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 5)
33 // CHECK: ret [[A]]* [[CAST]]
34 // CHECK: call void @_ZdlPv(i8* [[NEW]])
35 return new A(5);
36 }
37
38 A *b() {
39 // CHECK: define [[A:%.*]]* @_ZN5test11bEv()
40 // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
41 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
42 // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv()
43 // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[FOO]])
44 // CHECK: ret [[A]]* [[CAST]]
45 // CHECK: call void @_ZdlPv(i8* [[NEW]])
46 extern int foo();
47 return new A(foo());
48 }
49
50 struct B { B(); ~B(); operator int(); int x; };
51 B makeB();
52
53 A *c() {
54 // CHECK: define [[A:%.*]]* @_ZN5test11cEv()
55 // CHECK: [[ACTIVE:%.*]] = alloca i1
56 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
57 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
58 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
59 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
60 // CHECK: [[T1:%.*]] = getelementptr inbounds [[B]]* [[T0]], i32 0, i32 0
61 // CHECK-NEXT: [[T2:%.*]] = load i32* [[T1]], align 4
62 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]])
63 // CHECK: store i1 false, i1* [[ACTIVE]]
64 // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
65 // CHECK: ret [[A]]* [[CAST]]
66 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
67 // CHECK-NEXT: br i1 [[ISACTIVE]]
68 // CHECK: call void @_ZdlPv(i8* [[NEW]])
69 return new A(B().x);
70 }
71
72 A *d() {
73 // CHECK: define [[A:%.*]]* @_ZN5test11dEv()
74 // CHECK: [[ACTIVE:%.*]] = alloca i1
75 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
76 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
77 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
78 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
79 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
80 // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
81 // CHECK: store i1 false, i1* [[ACTIVE]]
82 // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
83 // CHECK: ret [[A]]* [[CAST]]
84 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
85 // CHECK-NEXT: br i1 [[ISACTIVE]]
86 // CHECK: call void @_ZdlPv(i8* [[NEW]])
87 return new A(B());
88 }
89
90 A *e() {
91 // CHECK: define [[A:%.*]]* @_ZN5test11eEv()
92 // CHECK: [[ACTIVE:%.*]] = alloca i1
93 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
94 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
95 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
96 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
97 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
98 // CHECK: invoke void @_ZN5test11BC1Ev([[B]]* [[T2:%.*]])
99 // CHECK: [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T2]])
100 // CHECK: invoke void @_ZN5test11AC1Eii([[A]]* [[CAST]], i32 [[T1]], i32 [[T3]])
101 // CHECK: store i1 false, i1* [[ACTIVE]]
102 // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
103 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
104 // CHECK: ret [[A]]* [[CAST]]
105 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
106 // CHECK-NEXT: br i1 [[ISACTIVE]]
107 // CHECK: call void @_ZdlPv(i8* [[NEW]])
108 return new A(B(), B());
109 }
110 A *f() {
111 return new A(makeB().x);
112 }
113 A *g() {
114 return new A(makeB());
115 }
116 A *h() {
117 return new A(makeB(), makeB());
118 }
119
120 A *i() {
121 // CHECK: define [[A:%.*]]* @_ZN5test11iEv()
122 // CHECK: [[X:%.*]] = alloca [[A]]*, align 8
123 // CHECK: [[ACTIVE:%.*]] = alloca i1
124 // CHECK: store i1 true, i1* [[ACTIVE]]
125 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
126 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
127 // CHECK-NEXT: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T0:%.*]])
128 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
129 // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
130 // CHECK: store i1 false, i1* [[ACTIVE]]
131 // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8
132 // CHECK: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]])
133 // CHECK: [[RET:%.*]] = load [[A]]** [[X]], align 8
134 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
135 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
136 // CHECK: ret [[A]]* [[RET]]
137 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
138 // CHECK-NEXT: br i1 [[ISACTIVE]]
139 // CHECK: call void @_ZdlPv(i8* [[NEW]])
140 A *x;
141 return (x = new A(makeB()), makeB(), x);
142 }
143}
144
145namespace test2 {
146 struct A {
147 A(int); A(int, int); ~A();
148 void *p;
149 void *operator new(size_t);
150 void operator delete(void*, size_t);
151 };
152
153 A *a() {
154 // CHECK: define [[A:%.*]]* @_ZN5test21aEv()
155 // CHECK: [[NEW:%.*]] = call i8* @_ZN5test21AnwEm(i64 8)
156 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
157 // CHECK-NEXT: invoke void @_ZN5test21AC1Ei([[A]]* [[CAST]], i32 5)
158 // CHECK: ret [[A]]* [[CAST]]
159 // CHECK: invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
160 // CHECK: call void @_ZSt9terminatev()
161 return new A(5);
162 }
163}
164
165namespace test3 {
166 struct A {
John McCall3019c442010-09-17 00:50:28 +0000167 A(int); A(int, int); A(const A&); ~A();
John McCall7d8647f2010-09-14 07:57:04 +0000168 void *p;
John McCall3019c442010-09-17 00:50:28 +0000169 void *operator new(size_t, void*, double);
170 void operator delete(void*, void*, double);
John McCall7d8647f2010-09-14 07:57:04 +0000171 };
172
John McCall3019c442010-09-17 00:50:28 +0000173 void *foo();
174 double bar();
175 A makeA(), *makeAPtr();
176
John McCall7d8647f2010-09-14 07:57:04 +0000177 A *a() {
178 // CHECK: define [[A:%.*]]* @_ZN5test31aEv()
179 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
John McCall3019c442010-09-17 00:50:28 +0000180 // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv()
181 // CHECK: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[BAR]])
John McCall7d8647f2010-09-14 07:57:04 +0000182 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
183 // CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5)
184 // CHECK: ret [[A]]* [[CAST]]
John McCall3019c442010-09-17 00:50:28 +0000185 // CHECK: invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
John McCall7d8647f2010-09-14 07:57:04 +0000186 // CHECK: call void @_ZSt9terminatev()
John McCall7d8647f2010-09-14 07:57:04 +0000187 return new(foo(),bar()) A(5);
188 }
John McCall3019c442010-09-17 00:50:28 +0000189
190 // rdar://problem/8439196
191 A *b(bool cond) {
192
193 // CHECK: define [[A:%.*]]* @_ZN5test31bEb(i1 zeroext
194 // CHECK: [[SAVED0:%.*]] = alloca i8*
195 // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8*
196 // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
197 // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8
198 // CHECK: [[TMPACTIVE:%.*]] = alloca i1
John McCall3019c442010-09-17 00:50:28 +0000199 // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
200
201 // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
John McCall4bbcbda2011-01-26 19:15:39 +0000202 // CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]]
John McCall3019c442010-09-17 00:50:28 +0000203 // CHECK-NEXT: br i1 [[COND]]
204 return (cond ?
205
206 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
207 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[CONST:.*]])
208 // CHECK-NEXT: store i8* [[NEW]], i8** [[SAVED0]]
209 // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]]
210 // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]]
211 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
212 // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[TMP]])
213 // CHECK: store i1 true, i1* [[TMPACTIVE]]
214 // CHECK-NEXT: invoke void @_ZN5test31AC1ERKS0_([[A]]* [[CAST]], [[A]]* [[TMP]])
215 // CHECK: store i1 false, i1* [[CLEANUPACTIVE]]
216 // CHECK-NEXT: br label
217 // -> cond.end
218 new(foo(),10.0) A(makeA()) :
219
220 // CHECK: [[MAKE:%.*]] = invoke [[A]]* @_ZN5test38makeAPtrEv()
221 // CHECK: br label
222 // -> cond.end
223 makeAPtr());
224
225 // cond.end:
226 // CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
227 // CHECK-NEXT: [[ISACTIVE:%.*]] = load i1* [[TMPACTIVE]]
228 // CHECK-NEXT: br i1 [[ISACTIVE]]
229 // CHECK: invoke void @_ZN5test31AD1Ev
230 // CHECK: ret [[A]]* [[RESULT]]
231
232 // in the EH path:
233 // CHECK: [[ISACTIVE:%.*]] = load i1* [[CLEANUPACTIVE]]
234 // CHECK-NEXT: br i1 [[ISACTIVE]]
235 // CHECK: [[V0:%.*]] = load i8** [[SAVED0]]
236 // CHECK-NEXT: [[V1:%.*]] = load i8** [[SAVED1]]
237 // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
238 }
John McCall7d8647f2010-09-14 07:57:04 +0000239}
240
241namespace test4 {
242 struct A {
243 A(int); A(int, int); ~A();
244 void *p;
245 void *operator new(size_t, void*, void*);
246 void operator delete(void*, size_t, void*, void*); // not a match
247 };
248
249 A *a() {
250 // CHECK: define [[A:%.*]]* @_ZN5test41aEv()
251 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test43fooEv()
252 // CHECK-NEXT: [[BAR:%.*]] = call i8* @_ZN5test43barEv()
253 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test41AnwEmPvS1_(i64 8, i8* [[FOO]], i8* [[BAR]])
254 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
255 // CHECK-NEXT: call void @_ZN5test41AC1Ei([[A]]* [[CAST]], i32 5)
256 // CHECK-NEXT: ret [[A]]* [[CAST]]
257 extern void *foo(), *bar();
258
259 return new(foo(),bar()) A(5);
260 }
Anders Carlsson8370c582009-12-11 00:32:37 +0000261}
John McCalle996ffd2011-02-16 08:02:54 +0000262
263// PR7908
264namespace test5 {
265 struct T { T(); ~T(); };
266
267 struct A {
268 A(const A &x, const T &t = T());
269 ~A();
270 };
271
272 void foo();
273
274 // CHECK: define void @_ZN5test54testEv()
275 // CHECK: [[EXNSLOT:%.*]] = alloca i8*
276 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
277 // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
278 // CHECK-NEXT: alloca i32
279 // CHECK-NEXT: invoke void @_ZN5test53fooEv()
280 // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]]
281 // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]])
282 // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]*
283 // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]])
284 // CHECK: invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* [[SRC]], [[T_T]]* [[T]])
285 // CHECK: invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]])
286 // CHECK: call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind
287 // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]])
288 // CHECK: call void @__cxa_end_catch()
289 void test() {
290 try {
291 foo();
292 } catch (A a) {
293 }
294 }
295}