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