blob: 2a5cbb49005e2a27d64f93bcecb03816430634d2 [file] [log] [blame]
Anders Carlssonabea9512011-02-28 00:40:07 +00001// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -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
John McCall7d8647f2010-09-14 07:57:04 +000056 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
John McCall6f103ba2011-11-10 10:43:54 +000057 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall7d8647f2010-09-14 07:57:04 +000058 // 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
John McCall7d8647f2010-09-14 07:57:04 +000075 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
John McCall6f103ba2011-11-10 10:43:54 +000076 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall7d8647f2010-09-14 07:57:04 +000077 // 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
John McCall7d8647f2010-09-14 07:57:04 +000093 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
John McCall6f103ba2011-11-10 10:43:54 +000094 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall7d8647f2010-09-14 07:57:04 +000095 // 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
John McCall6f103ba2011-11-10 10:43:54 +0000124 // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
125 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall7d8647f2010-09-14 07:57:04 +0000126 // 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
200 // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
John McCall6f103ba2011-11-10 10:43:54 +0000201 // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
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*
John McCall93c332a2011-05-28 21:13:02 +0000276 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
John McCalle996ffd2011-02-16 08:02:54 +0000277 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
278 // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
John McCalle996ffd2011-02-16 08:02:54 +0000279 // 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}
John McCall27f8d702011-02-25 04:19:13 +0000296
297// PR9303: invalid assert on this
298namespace test6 {
299 bool cond();
300 void test() {
301 try {
302 lbl:
303 if (cond()) goto lbl;
304 } catch (...) {
305 }
306 }
307}
John McCalla7f633f2011-03-07 01:52:56 +0000308
309// PR9298
310namespace test7 {
311 struct A { A(); ~A(); };
312 struct B {
313 // The throw() operator means that a bad allocation is signalled
314 // with a null return, which means that the initializer is
315 // evaluated conditionally.
316 static void *operator new(size_t size) throw();
317 B(const A&, B*);
318 ~B();
319 };
320
John McCalla7f633f2011-03-07 01:52:56 +0000321 B *test() {
John McCallc2f3e7f2011-03-07 03:12:35 +0000322 // CHECK: define [[B:%.*]]* @_ZN5test74testEv()
323 // CHECK: [[OUTER_NEW:%.*]] = alloca i1
324 // CHECK-NEXT: alloca [[A:%.*]],
325 // CHECK-NEXT: alloca i8*
326 // CHECK-NEXT: alloca i32
327 // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
328 // CHECK-NEXT: alloca i8*
329 // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
330 // CHECK-NEXT: alloca [[A]]
331 // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1
332
John McCallc2f3e7f2011-03-07 03:12:35 +0000333 // Allocate the outer object.
334 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
335 // CHECK-NEXT: icmp eq i8* [[NEW]], null
336
337 // These stores, emitted before the outermost conditional branch,
338 // deactivate the temporary cleanups.
John McCall6f103ba2011-11-10 10:43:54 +0000339 // CHECK-NEXT: store i1 false, i1* [[OUTER_NEW]]
John McCallc2f3e7f2011-03-07 03:12:35 +0000340 // CHECK-NEXT: store i1 false, i1* [[OUTER_A]]
John McCall6f103ba2011-11-10 10:43:54 +0000341 // CHECK-NEXT: store i1 false, i1* [[INNER_NEW]]
John McCallc2f3e7f2011-03-07 03:12:35 +0000342 // CHECK-NEXT: store i1 false, i1* [[INNER_A]]
343 // CHECK-NEXT: br i1
344
345 // We passed the first null check; activate that cleanup and continue.
346 // CHECK: store i1 true, i1* [[OUTER_NEW]]
347 // CHECK-NEXT: bitcast
348
349 // Create the first A temporary and activate that cleanup.
350 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
351 // CHECK: store i1 true, i1* [[OUTER_A]]
352
353 // Allocate the inner object.
354 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
355 // CHECK-NEXT: icmp eq i8* [[NEW]], null
356 // CHECK-NEXT: br i1
357
358 // We passed the second null check; save that pointer, activate
359 // that cleanup, and continue.
360 // CHECK: store i8* [[NEW]]
361 // CHECK-NEXT: store i1 true, i1* [[INNER_NEW]]
362 // CHECK-NEXT: bitcast
363
364 // Build the second A temporary and activate that cleanup.
365 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
366 // CHECK: store i1 true, i1* [[INNER_A]]
367
368 // Build the inner B object and deactivate the inner delete cleanup.
369 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
370 // CHECK: store i1 false, i1* [[INNER_NEW]]
371 // CHECK: phi
372
373 // Build the outer B object and deactivate the outer delete cleanup.
374 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
375 // CHECK: store i1 false, i1* [[OUTER_NEW]]
376 // CHECK: phi
377
378 // Destroy the inner A object.
379 // CHECK-NEXT: load i1* [[INNER_A]]
380 // CHECK-NEXT: br i1
381 // CHECK: invoke void @_ZN5test71AD1Ev(
382
383 // Destroy the outer A object.
384 // CHECK: load i1* [[OUTER_A]]
385 // CHECK-NEXT: br i1
386 // CHECK: invoke void @_ZN5test71AD1Ev(
387
John McCalla7f633f2011-03-07 01:52:56 +0000388 return new B(A(), new B(A(), 0));
389 }
390}
John McCall13668622011-08-26 00:46:38 +0000391
392// Just don't crash.
393namespace test8 {
394 struct A {
John McCall90b2bdf2011-08-26 05:38:08 +0000395 // Having both of these is required to trigger the assert we're
396 // trying to avoid.
John McCall13668622011-08-26 00:46:38 +0000397 A(const A&);
John McCall90b2bdf2011-08-26 05:38:08 +0000398 A&operator=(const A&);
399
John McCall13668622011-08-26 00:46:38 +0000400 ~A();
401 };
402
403 A makeA();
404 void test() {
405 throw makeA();
406 }
Eli Friedman576cf172011-09-06 18:53:03 +0000407 // CHECK: define void @_ZN5test84testEv
408}
409
410// Make sure we generate the correct code for the delete[] call which
411// happens if A::A() throws. (We were previously calling delete[] on
412// a pointer to the first array element, not the pointer returned by new[].)
413// PR10870
414namespace test9 {
415 struct A {
416 A();
417 ~A();
418 };
419 A* test() {
420 return new A[10];
421 }
422 // CHECK: define {{%.*}}* @_ZN5test94testEv
423 // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam
424 // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]])
John McCall13668622011-08-26 00:46:38 +0000425}