xref: /aosp_15_r20/external/clang/test/CodeGenCXX/exceptions.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li typedef __typeof(sizeof(0)) size_t;
4*67e74705SXin Li 
5*67e74705SXin Li // Declare the reserved global placement new.
6*67e74705SXin Li void *operator new(size_t, void*);
7*67e74705SXin Li 
8*67e74705SXin Li // This just shouldn't crash.
9*67e74705SXin Li namespace test0 {
10*67e74705SXin Li   struct allocator {
11*67e74705SXin Li     allocator();
12*67e74705SXin Li     allocator(const allocator&);
13*67e74705SXin Li     ~allocator();
14*67e74705SXin Li   };
15*67e74705SXin Li 
16*67e74705SXin Li   void f();
g(bool b,bool c)17*67e74705SXin Li   void g(bool b, bool c) {
18*67e74705SXin Li     if (b) {
19*67e74705SXin Li       if (!c)
20*67e74705SXin Li         throw allocator();
21*67e74705SXin Li 
22*67e74705SXin Li       return;
23*67e74705SXin Li     }
24*67e74705SXin Li     f();
25*67e74705SXin Li   }
26*67e74705SXin Li }
27*67e74705SXin Li 
28*67e74705SXin Li namespace test1 {
29*67e74705SXin Li   struct A { A(int); A(int, int); ~A(); void *p; };
30*67e74705SXin Li 
a()31*67e74705SXin Li   A *a() {
32*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test11aEv()
33*67e74705SXin Li     // CHECK:      [[NEW:%.*]] = call i8* @_Znwm(i64 8)
34*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
35*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 5)
36*67e74705SXin Li     // CHECK:      ret [[A]]* [[CAST]]
37*67e74705SXin Li     // CHECK:      call void @_ZdlPv(i8* [[NEW]])
38*67e74705SXin Li     return new A(5);
39*67e74705SXin Li   }
40*67e74705SXin Li 
b()41*67e74705SXin Li   A *b() {
42*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test11bEv()
43*67e74705SXin Li     // CHECK:      [[NEW:%.*]] = call i8* @_Znwm(i64 8)
44*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
45*67e74705SXin Li     // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv()
46*67e74705SXin Li     // CHECK:      invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[FOO]])
47*67e74705SXin Li     // CHECK:      ret [[A]]* [[CAST]]
48*67e74705SXin Li     // CHECK:      call void @_ZdlPv(i8* [[NEW]])
49*67e74705SXin Li     extern int foo();
50*67e74705SXin Li     return new A(foo());
51*67e74705SXin Li   }
52*67e74705SXin Li 
53*67e74705SXin Li   struct B { B(); ~B(); operator int(); int x; };
54*67e74705SXin Li   B makeB();
55*67e74705SXin Li 
c()56*67e74705SXin Li   A *c() {
57*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test11cEv()
58*67e74705SXin Li     // CHECK:      [[ACTIVE:%.*]] = alloca i1
59*67e74705SXin Li     // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
60*67e74705SXin Li     // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
61*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
62*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
63*67e74705SXin Li     // CHECK:      [[T1:%.*]] = getelementptr inbounds [[B]], [[B]]* [[T0]], i32 0, i32 0
64*67e74705SXin Li     // CHECK-NEXT: [[T2:%.*]] = load i32, i32* [[T1]], align 4
65*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]])
66*67e74705SXin Li     // CHECK:      store i1 false, i1* [[ACTIVE]]
67*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
68*67e74705SXin Li     // CHECK:      ret [[A]]* [[CAST]]
69*67e74705SXin Li     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
70*67e74705SXin Li     // CHECK-NEXT: br i1 [[ISACTIVE]]
71*67e74705SXin Li     // CHECK:      call void @_ZdlPv(i8* [[NEW]])
72*67e74705SXin Li     return new A(B().x);
73*67e74705SXin Li   }
74*67e74705SXin Li 
75*67e74705SXin Li   //   rdar://11904428
76*67e74705SXin Li   //   Terminate landing pads should call __cxa_begin_catch first.
77*67e74705SXin Li   // CHECK:      define linkonce_odr hidden void @__clang_call_terminate(i8*) [[NI_NR_NUW:#[0-9]+]] comdat
78*67e74705SXin Li   // CHECK-NEXT:   [[T0:%.*]] = call i8* @__cxa_begin_catch(i8* %0) [[NUW:#[0-9]+]]
79*67e74705SXin Li   // CHECK-NEXT:   call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]]
80*67e74705SXin Li   // CHECK-NEXT:   unreachable
81*67e74705SXin Li 
d()82*67e74705SXin Li   A *d() {
83*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test11dEv()
84*67e74705SXin Li     // CHECK:      [[ACTIVE:%.*]] = alloca i1
85*67e74705SXin Li     // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
86*67e74705SXin Li     // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
87*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
88*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
89*67e74705SXin Li     // CHECK:      [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
90*67e74705SXin Li     // CHECK:      invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
91*67e74705SXin Li     // CHECK:      store i1 false, i1* [[ACTIVE]]
92*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
93*67e74705SXin Li     // CHECK:      ret [[A]]* [[CAST]]
94*67e74705SXin Li     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
95*67e74705SXin Li     // CHECK-NEXT: br i1 [[ISACTIVE]]
96*67e74705SXin Li     // CHECK:      call void @_ZdlPv(i8* [[NEW]])
97*67e74705SXin Li     return new A(B());
98*67e74705SXin Li   }
99*67e74705SXin Li 
e()100*67e74705SXin Li   A *e() {
101*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test11eEv()
102*67e74705SXin Li     // CHECK:      [[ACTIVE:%.*]] = alloca i1
103*67e74705SXin Li     // CHECK-NEXT: [[NEW:%.*]] = call i8* @_Znwm(i64 8)
104*67e74705SXin Li     // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
105*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
106*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
107*67e74705SXin Li     // CHECK:      [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
108*67e74705SXin Li     // CHECK:      invoke void @_ZN5test11BC1Ev([[B]]* [[T2:%.*]])
109*67e74705SXin Li     // CHECK:      [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T2]])
110*67e74705SXin Li     // CHECK:      invoke void @_ZN5test11AC1Eii([[A]]* [[CAST]], i32 [[T1]], i32 [[T3]])
111*67e74705SXin Li     // CHECK:      store i1 false, i1* [[ACTIVE]]
112*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
113*67e74705SXin Li     // CHECK:      invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
114*67e74705SXin Li     // CHECK:      ret [[A]]* [[CAST]]
115*67e74705SXin Li     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
116*67e74705SXin Li     // CHECK-NEXT: br i1 [[ISACTIVE]]
117*67e74705SXin Li     // CHECK:      call void @_ZdlPv(i8* [[NEW]])
118*67e74705SXin Li     return new A(B(), B());
119*67e74705SXin Li   }
f()120*67e74705SXin Li   A *f() {
121*67e74705SXin Li     return new A(makeB().x);
122*67e74705SXin Li   }
g()123*67e74705SXin Li   A *g() {
124*67e74705SXin Li     return new A(makeB());
125*67e74705SXin Li   }
h()126*67e74705SXin Li   A *h() {
127*67e74705SXin Li     return new A(makeB(), makeB());
128*67e74705SXin Li   }
129*67e74705SXin Li 
i()130*67e74705SXin Li   A *i() {
131*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test11iEv()
132*67e74705SXin Li     // CHECK:      [[X:%.*]] = alloca [[A]]*, align 8
133*67e74705SXin Li     // CHECK:      [[ACTIVE:%.*]] = alloca i1
134*67e74705SXin Li     // CHECK:      [[NEW:%.*]] = call i8* @_Znwm(i64 8)
135*67e74705SXin Li     // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
136*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
137*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T0:%.*]])
138*67e74705SXin Li     // CHECK:      [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
139*67e74705SXin Li     // CHECK:      invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
140*67e74705SXin Li     // CHECK:      store i1 false, i1* [[ACTIVE]]
141*67e74705SXin Li     // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8
142*67e74705SXin Li     // CHECK:      invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]])
143*67e74705SXin Li     // CHECK:      [[RET:%.*]] = load [[A]]*, [[A]]** [[X]], align 8
144*67e74705SXin Li     // CHECK:      invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
145*67e74705SXin Li     // CHECK:      invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
146*67e74705SXin Li     // CHECK:      ret [[A]]* [[RET]]
147*67e74705SXin Li     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]]
148*67e74705SXin Li     // CHECK-NEXT: br i1 [[ISACTIVE]]
149*67e74705SXin Li     // CHECK:      call void @_ZdlPv(i8* [[NEW]])
150*67e74705SXin Li     A *x;
151*67e74705SXin Li     return (x = new A(makeB()), makeB(), x);
152*67e74705SXin Li   }
153*67e74705SXin Li }
154*67e74705SXin Li 
155*67e74705SXin Li namespace test2 {
156*67e74705SXin Li   struct A {
157*67e74705SXin Li     A(int); A(int, int); ~A();
158*67e74705SXin Li     void *p;
159*67e74705SXin Li     void *operator new(size_t);
160*67e74705SXin Li     void operator delete(void*, size_t);
161*67e74705SXin Li   };
162*67e74705SXin Li 
a()163*67e74705SXin Li   A *a() {
164*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test21aEv()
165*67e74705SXin Li     // CHECK:      [[NEW:%.*]] = call i8* @_ZN5test21AnwEm(i64 8)
166*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
167*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test21AC1Ei([[A]]* [[CAST]], i32 5)
168*67e74705SXin Li     // CHECK:      ret [[A]]* [[CAST]]
169*67e74705SXin Li     // CHECK:      invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
170*67e74705SXin Li     // CHECK:      call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
171*67e74705SXin Li     return new A(5);
172*67e74705SXin Li   }
173*67e74705SXin Li }
174*67e74705SXin Li 
175*67e74705SXin Li namespace test3 {
176*67e74705SXin Li   struct A {
177*67e74705SXin Li     A(int); A(int, int); A(const A&); ~A();
178*67e74705SXin Li     void *p;
179*67e74705SXin Li     void *operator new(size_t, void*, double);
180*67e74705SXin Li     void operator delete(void*, void*, double);
181*67e74705SXin Li   };
182*67e74705SXin Li 
183*67e74705SXin Li   void *foo();
184*67e74705SXin Li   double bar();
185*67e74705SXin Li   A makeA(), *makeAPtr();
186*67e74705SXin Li 
a()187*67e74705SXin Li   A *a() {
188*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test31aEv()
189*67e74705SXin Li     // CHECK:      [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
190*67e74705SXin Li     // CHECK:      [[BAR:%.*]] = call double @_ZN5test33barEv()
191*67e74705SXin Li     // CHECK:      [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[BAR]])
192*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
193*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5)
194*67e74705SXin Li     // CHECK:      ret [[A]]* [[CAST]]
195*67e74705SXin Li     // CHECK:      invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
196*67e74705SXin Li     // CHECK:      call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
197*67e74705SXin Li     return new(foo(),bar()) A(5);
198*67e74705SXin Li   }
199*67e74705SXin Li 
200*67e74705SXin Li   // rdar://problem/8439196
b(bool cond)201*67e74705SXin Li   A *b(bool cond) {
202*67e74705SXin Li 
203*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test31bEb(i1 zeroext
204*67e74705SXin Li     // CHECK:      [[SAVED0:%.*]] = alloca i8*
205*67e74705SXin Li     // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8*
206*67e74705SXin Li     // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
207*67e74705SXin Li 
208*67e74705SXin Li     // CHECK:      [[COND:%.*]] = trunc i8 {{.*}} to i1
209*67e74705SXin Li     // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
210*67e74705SXin Li     // CHECK-NEXT: br i1 [[COND]]
211*67e74705SXin Li     return (cond ?
212*67e74705SXin Li 
213*67e74705SXin Li     // CHECK:      [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
214*67e74705SXin Li     // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[CONST:.*]])
215*67e74705SXin Li     // CHECK-NEXT: store i8* [[NEW]], i8** [[SAVED0]]
216*67e74705SXin Li     // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]]
217*67e74705SXin Li     // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]]
218*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
219*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[CAST]])
220*67e74705SXin Li     // CHECK: br label
221*67e74705SXin Li     //   -> cond.end
222*67e74705SXin Li             new(foo(),10.0) A(makeA()) :
223*67e74705SXin Li 
224*67e74705SXin Li     // CHECK:      [[MAKE:%.*]] = call [[A]]* @_ZN5test38makeAPtrEv()
225*67e74705SXin Li     // CHECK:      br label
226*67e74705SXin Li     //   -> cond.end
227*67e74705SXin Li             makeAPtr());
228*67e74705SXin Li 
229*67e74705SXin Li     // cond.end:
230*67e74705SXin Li     // CHECK:      [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
231*67e74705SXin Li     // CHECK:      ret [[A]]* [[RESULT]]
232*67e74705SXin Li 
233*67e74705SXin Li     // in the EH path:
234*67e74705SXin Li     // CHECK:      [[ISACTIVE:%.*]] = load i1, i1* [[CLEANUPACTIVE]]
235*67e74705SXin Li     // CHECK-NEXT: br i1 [[ISACTIVE]]
236*67e74705SXin Li     // CHECK:      [[V0:%.*]] = load i8*, i8** [[SAVED0]]
237*67e74705SXin Li     // CHECK-NEXT: [[V1:%.*]] = load i8*, i8** [[SAVED1]]
238*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
239*67e74705SXin Li   }
240*67e74705SXin Li }
241*67e74705SXin Li 
242*67e74705SXin Li namespace test4 {
243*67e74705SXin Li   struct A {
244*67e74705SXin Li     A(int); A(int, int); ~A();
245*67e74705SXin Li     void *p;
246*67e74705SXin Li     void *operator new(size_t, void*, void*);
247*67e74705SXin Li     void operator delete(void*, size_t, void*, void*); // not a match
248*67e74705SXin Li   };
249*67e74705SXin Li 
a()250*67e74705SXin Li   A *a() {
251*67e74705SXin Li     // CHECK:    define [[A:%.*]]* @_ZN5test41aEv()
252*67e74705SXin Li     // CHECK:      [[FOO:%.*]] = call i8* @_ZN5test43fooEv()
253*67e74705SXin Li     // CHECK-NEXT: [[BAR:%.*]] = call i8* @_ZN5test43barEv()
254*67e74705SXin Li     // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test41AnwEmPvS1_(i64 8, i8* [[FOO]], i8* [[BAR]])
255*67e74705SXin Li     // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
256*67e74705SXin Li     // CHECK-NEXT: call void @_ZN5test41AC1Ei([[A]]* [[CAST]], i32 5)
257*67e74705SXin Li     // CHECK-NEXT: ret [[A]]* [[CAST]]
258*67e74705SXin Li     extern void *foo(), *bar();
259*67e74705SXin Li 
260*67e74705SXin Li     return new(foo(),bar()) A(5);
261*67e74705SXin Li   }
262*67e74705SXin Li }
263*67e74705SXin Li 
264*67e74705SXin Li // PR7908
265*67e74705SXin Li namespace test5 {
266*67e74705SXin Li   struct T { T(); ~T(); };
267*67e74705SXin Li 
268*67e74705SXin Li   struct A {
269*67e74705SXin Li     A(const A &x, const T &t = T());
270*67e74705SXin Li     ~A();
271*67e74705SXin Li   };
272*67e74705SXin Li 
273*67e74705SXin Li   void foo();
274*67e74705SXin Li 
275*67e74705SXin Li   // CHECK-LABEL:    define void @_ZN5test54testEv()
276*67e74705SXin Li   // CHECK:      [[EXNSLOT:%.*]] = alloca i8*
277*67e74705SXin Li   // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
278*67e74705SXin Li   // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
279*67e74705SXin Li   // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
280*67e74705SXin Li   // CHECK-NEXT: invoke void @_ZN5test53fooEv()
281*67e74705SXin Li   // CHECK:      [[EXN:%.*]] = load i8*, i8** [[EXNSLOT]]
282*67e74705SXin Li   // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]])
283*67e74705SXin Li   // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]*
284*67e74705SXin Li   // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]])
285*67e74705SXin Li   // CHECK:      invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* dereferenceable({{[0-9]+}}) [[SRC]], [[T_T]]* dereferenceable({{[0-9]+}}) [[T]])
286*67e74705SXin Li   // CHECK:      invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]])
287*67e74705SXin Li   // CHECK:      call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]]
288*67e74705SXin Li   // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]])
289*67e74705SXin Li   // CHECK:      call void @__cxa_end_catch()
test()290*67e74705SXin Li   void test() {
291*67e74705SXin Li     try {
292*67e74705SXin Li       foo();
293*67e74705SXin Li     } catch (A a) {
294*67e74705SXin Li     }
295*67e74705SXin Li   }
296*67e74705SXin Li }
297*67e74705SXin Li 
298*67e74705SXin Li // PR9303: invalid assert on this
299*67e74705SXin Li namespace test6 {
300*67e74705SXin Li   bool cond();
test()301*67e74705SXin Li   void test() {
302*67e74705SXin Li     try {
303*67e74705SXin Li     lbl:
304*67e74705SXin Li       if (cond()) goto lbl;
305*67e74705SXin Li     } catch (...) {
306*67e74705SXin Li     }
307*67e74705SXin Li   }
308*67e74705SXin Li }
309*67e74705SXin Li 
310*67e74705SXin Li // PR9298
311*67e74705SXin Li namespace test7 {
312*67e74705SXin Li   struct A { A(); ~A(); };
313*67e74705SXin Li   struct B {
314*67e74705SXin Li     // The throw() operator means that a bad allocation is signalled
315*67e74705SXin Li     // with a null return, which means that the initializer is
316*67e74705SXin Li     // evaluated conditionally.
317*67e74705SXin Li     static void *operator new(size_t size) throw();
318*67e74705SXin Li     B(const A&, B*);
319*67e74705SXin Li     ~B();
320*67e74705SXin Li   };
321*67e74705SXin Li 
test()322*67e74705SXin Li   B *test() {
323*67e74705SXin Li     // CHECK: define [[B:%.*]]* @_ZN5test74testEv()
324*67e74705SXin Li     // CHECK:      [[OUTER_NEW:%.*]] = alloca i1
325*67e74705SXin Li     // CHECK-NEXT: alloca [[A:%.*]],
326*67e74705SXin Li     // CHECK-NEXT: alloca i8*
327*67e74705SXin Li     // CHECK-NEXT: alloca i32
328*67e74705SXin Li     // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
329*67e74705SXin Li     // CHECK-NEXT: alloca i8*
330*67e74705SXin Li     // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
331*67e74705SXin Li     // CHECK-NEXT: alloca [[A]]
332*67e74705SXin Li     // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1
333*67e74705SXin Li 
334*67e74705SXin Li     // Allocate the outer object.
335*67e74705SXin Li     // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
336*67e74705SXin Li     // CHECK-NEXT: icmp eq i8* [[NEW]], null
337*67e74705SXin Li 
338*67e74705SXin Li     // These stores, emitted before the outermost conditional branch,
339*67e74705SXin Li     // deactivate the temporary cleanups.
340*67e74705SXin Li     // CHECK-NEXT: store i1 false, i1* [[OUTER_NEW]]
341*67e74705SXin Li     // CHECK-NEXT: store i1 false, i1* [[OUTER_A]]
342*67e74705SXin Li     // CHECK-NEXT: store i1 false, i1* [[INNER_NEW]]
343*67e74705SXin Li     // CHECK-NEXT: store i1 false, i1* [[INNER_A]]
344*67e74705SXin Li     // CHECK-NEXT: br i1
345*67e74705SXin Li 
346*67e74705SXin Li     // We passed the first null check; activate that cleanup and continue.
347*67e74705SXin Li     // CHECK:      store i1 true, i1* [[OUTER_NEW]]
348*67e74705SXin Li     // CHECK-NEXT: bitcast
349*67e74705SXin Li 
350*67e74705SXin Li     // Create the first A temporary and activate that cleanup.
351*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
352*67e74705SXin Li     // CHECK:      store i1 true, i1* [[OUTER_A]]
353*67e74705SXin Li 
354*67e74705SXin Li     // Allocate the inner object.
355*67e74705SXin Li     // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
356*67e74705SXin Li     // CHECK-NEXT: icmp eq i8* [[NEW]], null
357*67e74705SXin Li     // CHECK-NEXT: br i1
358*67e74705SXin Li 
359*67e74705SXin Li     // We passed the second null check; save that pointer, activate
360*67e74705SXin Li     // that cleanup, and continue.
361*67e74705SXin Li     // CHECK:      store i8* [[NEW]]
362*67e74705SXin Li     // CHECK-NEXT: store i1 true, i1* [[INNER_NEW]]
363*67e74705SXin Li     // CHECK-NEXT: bitcast
364*67e74705SXin Li 
365*67e74705SXin Li     // Build the second A temporary and activate that cleanup.
366*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
367*67e74705SXin Li     // CHECK:      store i1 true, i1* [[INNER_A]]
368*67e74705SXin Li 
369*67e74705SXin Li     // Build the inner B object and deactivate the inner delete cleanup.
370*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
371*67e74705SXin Li     // CHECK:      store i1 false, i1* [[INNER_NEW]]
372*67e74705SXin Li     // CHECK:      phi
373*67e74705SXin Li 
374*67e74705SXin Li     // Build the outer B object and deactivate the outer delete cleanup.
375*67e74705SXin Li     // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
376*67e74705SXin Li     // CHECK:      store i1 false, i1* [[OUTER_NEW]]
377*67e74705SXin Li     // CHECK:      phi
378*67e74705SXin Li     // CHECK-NEXT: store [[B]]*
379*67e74705SXin Li 
380*67e74705SXin Li     // Destroy the inner A object.
381*67e74705SXin Li     // CHECK-NEXT: load i1, i1* [[INNER_A]]
382*67e74705SXin Li     // CHECK-NEXT: br i1
383*67e74705SXin Li     // CHECK:      invoke void @_ZN5test71AD1Ev(
384*67e74705SXin Li 
385*67e74705SXin Li     // Destroy the outer A object.
386*67e74705SXin Li     // CHECK:      load i1, i1* [[OUTER_A]]
387*67e74705SXin Li     // CHECK-NEXT: br i1
388*67e74705SXin Li     // CHECK:      invoke void @_ZN5test71AD1Ev(
389*67e74705SXin Li 
390*67e74705SXin Li     return new B(A(), new B(A(), 0));
391*67e74705SXin Li   }
392*67e74705SXin Li }
393*67e74705SXin Li 
394*67e74705SXin Li // Just don't crash.
395*67e74705SXin Li namespace test8 {
396*67e74705SXin Li   struct A {
397*67e74705SXin Li     // Having both of these is required to trigger the assert we're
398*67e74705SXin Li     // trying to avoid.
399*67e74705SXin Li     A(const A&);
400*67e74705SXin Li     A&operator=(const A&);
401*67e74705SXin Li 
402*67e74705SXin Li     ~A();
403*67e74705SXin Li   };
404*67e74705SXin Li 
405*67e74705SXin Li   A makeA();
test()406*67e74705SXin Li   void test() {
407*67e74705SXin Li     throw makeA();
408*67e74705SXin Li   }
409*67e74705SXin Li   // CHECK-LABEL: define void @_ZN5test84testEv
410*67e74705SXin Li }
411*67e74705SXin Li 
412*67e74705SXin Li // Make sure we generate the correct code for the delete[] call which
413*67e74705SXin Li // happens if A::A() throws.  (We were previously calling delete[] on
414*67e74705SXin Li // a pointer to the first array element, not the pointer returned by new[].)
415*67e74705SXin Li // PR10870
416*67e74705SXin Li namespace test9 {
417*67e74705SXin Li   struct A {
418*67e74705SXin Li     A();
419*67e74705SXin Li     ~A();
420*67e74705SXin Li   };
test()421*67e74705SXin Li   A* test() {
422*67e74705SXin Li     return new A[10];
423*67e74705SXin Li   }
424*67e74705SXin Li   // CHECK: define {{%.*}}* @_ZN5test94testEv
425*67e74705SXin Li   // CHECK: [[TEST9_NEW:%.*]] = call i8* @_Znam
426*67e74705SXin Li   // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]])
427*67e74705SXin Li }
428*67e74705SXin Li 
429*67e74705SXin Li // In a destructor with a function-try-block, a return statement in a
430*67e74705SXin Li // catch handler behaves differently from running off the end of the
431*67e74705SXin Li // catch handler.  PR13102.
432*67e74705SXin Li namespace test10 {
433*67e74705SXin Li   extern void cleanup();
434*67e74705SXin Li   extern bool suppress;
435*67e74705SXin Li 
436*67e74705SXin Li   struct A { ~A(); };
~A()437*67e74705SXin Li   A::~A() try { cleanup(); } catch (...) { return; }
438*67e74705SXin Li   // CHECK-LABEL:    define void @_ZN6test101AD1Ev(
439*67e74705SXin Li   // CHECK:      invoke void @_ZN6test107cleanupEv()
440*67e74705SXin Li   // CHECK-NOT:  rethrow
441*67e74705SXin Li   // CHECK:      ret void
442*67e74705SXin Li 
443*67e74705SXin Li   struct B { ~B(); };
~B()444*67e74705SXin Li   B::~B() try { cleanup(); } catch (...) {}
445*67e74705SXin Li   // CHECK-LABEL:    define void @_ZN6test101BD1Ev(
446*67e74705SXin Li   // CHECK:      invoke void @_ZN6test107cleanupEv()
447*67e74705SXin Li   // CHECK:      call i8* @__cxa_begin_catch
448*67e74705SXin Li   // CHECK-NEXT: invoke void @__cxa_rethrow()
449*67e74705SXin Li   // CHECK:      unreachable
450*67e74705SXin Li 
451*67e74705SXin Li   struct C { ~C(); };
~C()452*67e74705SXin Li   C::~C() try { cleanup(); } catch (...) { if (suppress) return; }
453*67e74705SXin Li   // CHECK-LABEL:    define void @_ZN6test101CD1Ev(
454*67e74705SXin Li   // CHECK:      invoke void @_ZN6test107cleanupEv()
455*67e74705SXin Li   // CHECK:      call i8* @__cxa_begin_catch
456*67e74705SXin Li   // CHECK-NEXT: load i8, i8* @_ZN6test108suppressE, align 1
457*67e74705SXin Li   // CHECK-NEXT: trunc
458*67e74705SXin Li   // CHECK-NEXT: br i1
459*67e74705SXin Li   // CHECK:      call void @__cxa_end_catch()
460*67e74705SXin Li   // CHECK-NEXT: br label
461*67e74705SXin Li   // CHECK:      invoke void @__cxa_rethrow()
462*67e74705SXin Li   // CHECK:      unreachable
463*67e74705SXin Li }
464*67e74705SXin Li 
465*67e74705SXin Li // Ensure that an exception in a constructor destroys
466*67e74705SXin Li // already-constructed array members.  PR14514
467*67e74705SXin Li namespace test11 {
468*67e74705SXin Li   struct A {
469*67e74705SXin Li     A();
~Atest11::A470*67e74705SXin Li     ~A() {}
471*67e74705SXin Li   };
472*67e74705SXin Li 
473*67e74705SXin Li   struct C {
474*67e74705SXin Li     A single;
475*67e74705SXin Li     A array[2][3];
476*67e74705SXin Li 
477*67e74705SXin Li     C();
478*67e74705SXin Li   };
479*67e74705SXin Li 
C()480*67e74705SXin Li   C::C() {
481*67e74705SXin Li     throw 0;
482*67e74705SXin Li   }
483*67e74705SXin Li   // CHECK-LABEL:    define void @_ZN6test111CC2Ev(
484*67e74705SXin Li   // CHECK:      [[THIS:%.*]] = load [[C:%.*]]*, [[C:%.*]]** {{%.*}}
485*67e74705SXin Li   //   Construct single.
486*67e74705SXin Li   // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C]], [[C]]* [[THIS]], i32 0, i32 0
487*67e74705SXin Li   // CHECK-NEXT: call void @_ZN6test111AC1Ev([[A:%.*]]* [[SINGLE]])
488*67e74705SXin Li   //   Construct array.
489*67e74705SXin Li   // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C]], [[C]]* [[THIS]], i32 0, i32 1
490*67e74705SXin Li   // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
491*67e74705SXin Li   // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ARRAYBEGIN]], i64 6
492*67e74705SXin Li   // CHECK-NEXT: br label
493*67e74705SXin Li   // CHECK:      [[CUR:%.*]] = phi [[A]]* [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
494*67e74705SXin Li   // CHECK-NEXT: invoke void @_ZN6test111AC1Ev([[A:%.*]]* [[CUR]])
495*67e74705SXin Li   // CHECK:      [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1
496*67e74705SXin Li   // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[ARRAYEND]]
497*67e74705SXin Li   // CHECK-NEXT: br i1 [[DONE]],
498*67e74705SXin Li   //   throw 0;
499*67e74705SXin Li   // CHECK:      invoke void @__cxa_throw(
500*67e74705SXin Li   //   Landing pad 1, from constructor in array-initialization loop:
501*67e74705SXin Li   // CHECK:      landingpad
502*67e74705SXin Li   //     - First, destroy already-constructed bits of array.
503*67e74705SXin Li   // CHECK:      [[EMPTY:%.*]] = icmp eq [[A]]* [[ARRAYBEGIN]], [[CUR]]
504*67e74705SXin Li   // CHECK-NEXT: br i1 [[EMPTY]]
505*67e74705SXin Li   // CHECK:      [[AFTER:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
506*67e74705SXin Li   // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
507*67e74705SXin Li   // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
508*67e74705SXin Li   // CHECK:      [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
509*67e74705SXin Li   // CHECK-NEXT: br i1 [[DONE]],
510*67e74705SXin Li   //     - Next, chain to cleanup for single.
511*67e74705SXin Li   // CHECK:      br label
512*67e74705SXin Li   //   Landing pad 2, from throw site.
513*67e74705SXin Li   // CHECK:      landingpad
514*67e74705SXin Li   //     - First, destroy all of array.
515*67e74705SXin Li   // CHECK:      [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
516*67e74705SXin Li   // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ARRAYBEGIN]], i64 6
517*67e74705SXin Li   // CHECK-NEXT: br label
518*67e74705SXin Li   // CHECK:      [[AFTER:%.*]] = phi [[A]]* [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
519*67e74705SXin Li   // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
520*67e74705SXin Li   // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
521*67e74705SXin Li   // CHECK:      [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
522*67e74705SXin Li   // CHECK-NEXT: br i1 [[DONE]],
523*67e74705SXin Li   //     - Next, chain to cleanup for single.
524*67e74705SXin Li   // CHECK:      br label
525*67e74705SXin Li   //   Finally, the cleanup for single.
526*67e74705SXin Li   // CHECK:      invoke void @_ZN6test111AD1Ev([[A]]* [[SINGLE]])
527*67e74705SXin Li   // CHECK:      br label
528*67e74705SXin Li   // CHECK:      resume
529*67e74705SXin Li   //   (After this is a terminate landingpad.)
530*67e74705SXin Li }
531*67e74705SXin Li 
532*67e74705SXin Li namespace test12 {
533*67e74705SXin Li   struct A {
534*67e74705SXin Li     void operator delete(void *, void *);
535*67e74705SXin Li     A();
536*67e74705SXin Li   };
537*67e74705SXin Li 
test(void * ptr)538*67e74705SXin Li   A *test(void *ptr) {
539*67e74705SXin Li     return new (ptr) A();
540*67e74705SXin Li   }
541*67e74705SXin Li   // CHECK-LABEL: define {{.*}} @_ZN6test124testEPv(
542*67e74705SXin Li   // CHECK:       [[PTR:%.*]] = load i8*, i8*
543*67e74705SXin Li   // CHECK-NEXT:  [[CAST:%.*]] = bitcast i8* [[PTR]] to [[A:%.*]]*
544*67e74705SXin Li   // CHECK-NEXT:  invoke void @_ZN6test121AC1Ev([[A]]* [[CAST]])
545*67e74705SXin Li   // CHECK:       ret [[A]]* [[CAST]]
546*67e74705SXin Li   // CHECK:       invoke void @_ZN6test121AdlEPvS1_(i8* [[PTR]], i8* [[PTR]])
547*67e74705SXin Li }
548*67e74705SXin Li 
549*67e74705SXin Li // CHECK: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind }
550