eh.cpp revision 09faeabf39a6fab2e2beb6bf03da970c17d2049a
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 4struct test1_D { 5 double d; 6} d1; 7 8void 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 27struct test2_D { 28 test2_D(const test2_D&o); 29 test2_D(); 30 virtual void bar() { } 31 int i; int j; 32} d2; 33 34void 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 55struct test3_D { 56 test3_D() { } 57 test3_D(volatile test3_D&o); 58 virtual void bar(); 59}; 60 61void 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 79void 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 89namespace 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 109namespace test6 { 110 template <class T> struct allocator { 111 ~allocator() throw() { } 112 }; 113 114 void foo() { 115 allocator<int> a; 116 } 117} 118 119// PR7127 120namespace 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. 169namespace 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 185 // CHECK: call void @__cxa_end_catch() 186 // CHECK-NEXT: load 187 // CHECK-NEXT: switch 188 189 // CHECK: ret void 190 } 191 } 192} 193 194// Constructor function-try-block must rethrow on fallthrough. 195// rdar://problem/7696603 196namespace test9 { 197 void opaque(); 198 199 struct A { A(); }; 200 201 // CHECK: define void @_ZN5test91AC1Ev 202 // CHECK: call void @_ZN5test91AC2Ev 203 // CHECK-NEXT: ret void 204 205 // CHECK: define void @_ZN5test91AC2Ev( 206 A::A() try { 207 // CHECK: invoke void @_ZN5test96opaqueEv() 208 opaque(); 209 } catch (int x) { 210 // CHECK: call i8* @__cxa_begin_catch 211 // CHECK: invoke void @_ZN5test96opaqueEv() 212 // CHECK: invoke void @__cxa_rethrow() 213 opaque(); 214 } 215 216 // landing pad from first call to invoke 217 // CHECK: call i8* @llvm.eh.exception 218 // 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) 219} 220