]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGenCXX/eh.cpp
Update clang to r108428.
[FreeBSD/FreeBSD.git] / test / CodeGenCXX / eh.cpp
1 // RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll
2 // RUN: FileCheck --input-file=%t.ll %s
3
4 struct test1_D {
5   double d;
6 } d1;
7
8 void test1() {
9   throw d1;
10 }
11
12 // CHECK:     define void @_Z5test1v()
13 // CHECK:       [[FREEVAR:%.*]] = alloca i1
14 // CHECK-NEXT:  [[EXNOBJVAR:%.*]] = alloca i8*
15 // CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
16 // CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
17 // CHECK-NEXT:  store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
18 // CHECK-NEXT:  store i1 true, i1* [[FREEVAR]]
19 // CHECK-NEXT:  [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
20 // CHECK-NEXT:  [[EXN2:%.*]] = bitcast [[DSTAR]] [[EXN]] to i8*
21 // CHECK-NEXT:  call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXN2]], i8* bitcast ([[DSTAR]] @d1 to i8*), i64 8, i32 8, i1 false)
22 // CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
23 // CHECK-NEXT:  call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn
24 // CHECK-NEXT:  unreachable
25
26
27 struct test2_D {
28   test2_D(const test2_D&o);
29   test2_D();
30   virtual void bar() { }
31   int i; int j;
32 } d2;
33
34 void test2() {
35   throw d2;
36 }
37
38 // CHECK:     define void @_Z5test2v()
39 // CHECK:       [[FREEVAR:%.*]] = alloca i1
40 // CHECK-NEXT:  [[EXNOBJVAR:%.*]] = alloca i8*
41 // CHECK-NEXT:  [[EXNSLOTVAR:%.*]] = alloca i8*
42 // CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
43 // CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
44 // CHECK-NEXT:  store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
45 // CHECK-NEXT:  store i1 true, i1* [[FREEVAR]]
46 // CHECK-NEXT:  [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
47 // CHECK-NEXT:  invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2)
48 // CHECK-NEXT:     to label %[[CONT:.*]] unwind label %{{.*}}
49 //      :     [[CONT]]:   (can't check this in Release-Asserts builds)
50 // CHECK:       store i1 false, i1* [[FREEVAR]]
51 // CHECK-NEXT:  call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%{{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn
52 // CHECK-NEXT:  unreachable
53
54
55 struct test3_D {
56   test3_D() { }
57   test3_D(volatile test3_D&o);
58   virtual void bar();
59 };
60
61 void test3() {
62   throw (volatile test3_D *)0;
63 }
64
65 // CHECK:     define void @_Z5test3v()
66 // CHECK:       [[FREEVAR:%.*]] = alloca i1
67 // CHECK-NEXT:  [[EXNOBJVAR:%.*]] = alloca i8*
68 // CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
69 // CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
70 // CHECK-NEXT:  store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
71 // CHECK-NEXT:  store i1 true, i1* [[FREEVAR]]
72 // CHECK-NEXT:  [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSS:%[^*]*\*]]*
73 // CHECK-NEXT:  store [[DSS]] null, [[DSS]]* [[EXN]]
74 // CHECK-NEXT:  store i1 false, i1* [[FREEVAR]]
75 // CHECK-NEXT:  call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn
76 // CHECK-NEXT:  unreachable
77
78
79 void test4() {
80   throw;
81 }
82
83 // CHECK:     define void @_Z5test4v()
84 // CHECK:        call void @__cxa_rethrow() noreturn
85 // CHECK-NEXT:   unreachable
86
87
88 // rdar://problem/7696549
89 namespace test5 {
90   struct A {
91     A();
92     A(const A&);
93     ~A();
94   };
95
96   void test() {
97     try { throw A(); } catch (A &x) {}
98   }
99 // CHECK:      define void @_ZN5test54testEv()
100 // CHECK:      [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 1)
101 // CHECK:      [[EXNCAST:%.*]] = bitcast i8* [[EXNOBJ]] to [[A:%[^*]*]]*
102 // CHECK-NEXT: invoke void @_ZN5test51AC1Ev([[A]]* [[EXNCAST]])
103 // CHECK:      invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn
104 // CHECK-NEXT:   to label {{%.*}} unwind label %[[HANDLER:[^ ]*]]
105 //      :    [[HANDLER]]:  (can't check this in Release-Asserts builds)
106 // CHECK:      {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*))
107 }
108
109 namespace test6 {
110   template <class T> struct allocator {
111     ~allocator() throw() { }
112   };
113
114   void foo() {
115     allocator<int> a;
116   }
117 }
118
119 // PR7127
120 namespace test7 {
121 // CHECK:      define i32 @_ZN5test73fooEv() 
122   int foo() {
123 // CHECK:      [[FREEEXNOBJ:%.*]] = alloca i1
124 // CHECK-NEXT: [[EXNALLOCVAR:%.*]] = alloca i8*
125 // CHECK-NEXT: [[CAUGHTEXNVAR:%.*]] = alloca i8*
126 // CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32
127 // CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]]
128     try {
129       try {
130 // CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception
131 // CHECK-NEXT: store i8* [[EXNALLOC]], i8** [[EXNALLOCVAR]]
132 // CHECK-NEXT: store i1 true, i1* [[FREEEXNOBJ]]
133 // CHECK-NEXT: bitcast i8* [[EXNALLOC]] to i32*
134 // CHECK-NEXT: store i32 1, i32*
135 // CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]]
136 // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null
137         throw 1;
138       }
139
140 // CHECK:      [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
141 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
142 // CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
143 // CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
144 // CHECK-NEXT: icmp eq
145 // CHECK-NEXT: br i1
146 // CHECK:      load i8** [[CAUGHTEXNVAR]]
147 // CHECK-NEXT: call i8* @__cxa_begin_catch
148 // CHECK:      invoke void @__cxa_rethrow
149       catch (int) {
150         throw;
151       }
152     }
153 // CHECK:      [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
154 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
155 // CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null)
156 // CHECK-NEXT: call void @__cxa_end_catch()
157 // CHECK-NEXT: br label
158 // CHECK:      load i8** [[CAUGHTEXNVAR]]
159 // CHECK-NEXT: call i8* @__cxa_begin_catch
160 // CHECK-NEXT: call void @__cxa_end_catch
161     catch (...) {
162     }
163 // CHECK:      ret i32 0
164     return 0;
165   }
166 }
167
168 // Ordering of destructors in a catch handler.
169 namespace test8 {
170   struct A { A(const A&); ~A(); };
171   void bar();
172
173   // CHECK: define void @_ZN5test83fooEv()
174   void foo() {
175     try {
176       // CHECK:      invoke void @_ZN5test83barEv()
177       bar();
178     } catch (A a) {
179       // CHECK:      call i8* @__cxa_get_exception_ptr
180       // CHECK-NEXT: bitcast
181       // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_(
182       // CHECK:      call i8* @__cxa_begin_catch
183       // CHECK-NEXT: invoke void @_ZN5test81AD1Ev(
184       // CHECK:      call void @__cxa_end_catch()
185       // CHECK:      ret void
186     }
187   }
188 }
189
190 // Constructor function-try-block must rethrow on fallthrough.
191 // rdar://problem/7696603
192 namespace test9 {
193   void opaque();
194
195   struct A { A(); };
196
197   // CHECK:      define void @_ZN5test91AC1Ev
198   // CHECK:      call void @_ZN5test91AC2Ev
199   // CHECK-NEXT: ret void
200
201   // CHECK: define void @_ZN5test91AC2Ev(
202   A::A() try {
203   // CHECK:      invoke void @_ZN5test96opaqueEv()
204     opaque();
205   } catch (int x) {
206   // CHECK:      call i8* @__cxa_begin_catch
207   // CHECK:      invoke void @_ZN5test96opaqueEv()
208   // CHECK:      invoke void @__cxa_rethrow()
209     opaque();
210   }
211
212   // landing pad from first call to invoke
213   // CHECK:      call i8* @llvm.eh.exception
214   // CHECK:      call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
215 }
216
217 // __cxa_end_catch can throw for some kinds of caught exceptions.
218 namespace test10 {
219   void opaque();
220
221   struct A { ~A(); };
222   struct B { int x; };
223
224   // CHECK: define void @_ZN6test103fooEv()
225   void foo() {
226     A a; // force a cleanup context
227
228     try {
229     // CHECK:      invoke void @_ZN6test106opaqueEv()
230       opaque();
231     } catch (int i) {
232     // CHECK:      call i8* @__cxa_begin_catch
233     // CHECK-NEXT: bitcast
234     // CHECK-NEXT: load i32*
235     // CHECK-NEXT: store i32
236     // CHECK-NEXT: call void @__cxa_end_catch() nounwind
237     } catch (B a) {
238     // CHECK:      call i8* @__cxa_begin_catch
239     // CHECK-NEXT: bitcast
240     // CHECK-NEXT: bitcast
241     // CHECK-NEXT: bitcast
242     // CHECK-NEXT: call void @llvm.memcpy
243     // CHECK-NEXT: invoke void @__cxa_end_catch()
244     } catch (...) {
245     // CHECK:      call i8* @__cxa_begin_catch
246     // CHECK-NEXT: invoke void @__cxa_end_catch()
247     }
248
249     // CHECK: call void @_ZN6test101AD1Ev(
250   }
251 }