diff options
Diffstat (limited to 'test/CodeGenCXX/eh.cpp')
-rw-r--r-- | test/CodeGenCXX/eh.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index f2629d1..d03dc91 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -38,6 +38,7 @@ void test2() { // CHECK: define void @_Z5test2v() // CHECK: [[FREEVAR:%.*]] = alloca i1 // CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8* +// CHECK-NEXT: [[EXNSLOTVAR:%.*]] = alloca i8* // CHECK-NEXT: store i1 false, i1* [[FREEVAR]] // CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16) // CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]] @@ -104,3 +105,118 @@ namespace test5 { // : [[HANDLER]]: (can't check this in Release-Asserts builds) // CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*)) } + +namespace test6 { + template <class T> struct allocator { + ~allocator() throw() { } + }; + + void foo() { + allocator<int> a; + } +} + +// PR7127 +namespace test7 { +// CHECK: define i32 @_ZN5test73fooEv() + int foo() { +// CHECK: [[FREEEXNOBJ:%.*]] = alloca i1 +// CHECK-NEXT: [[EXNALLOCVAR:%.*]] = alloca i8* +// CHECK-NEXT: [[CAUGHTEXNVAR:%.*]] = alloca i8* +// CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32 +// CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]] + try { + try { +// CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception +// CHECK-NEXT: store i8* [[EXNALLOC]], i8** [[EXNALLOCVAR]] +// CHECK-NEXT: store i1 true, i1* [[FREEEXNOBJ]] +// CHECK-NEXT: bitcast i8* [[EXNALLOC]] to i32* +// CHECK-NEXT: store i32 1, i32* +// CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]] +// CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null + throw 1; + } +// This cleanup ends up here for no good reason. It's actually unused. +// CHECK: load i8** [[EXNALLOCVAR]] +// CHECK-NEXT: call void @__cxa_free_exception( + +// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception() +// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] +// 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) +// CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) +// CHECK-NEXT: icmp eq +// CHECK-NEXT: br i1 +// CHECK: load i8** [[CAUGHTEXNVAR]] +// CHECK-NEXT: call i8* @__cxa_begin_catch +// CHECK: invoke void @__cxa_rethrow + catch (int) { + throw; + } + } +// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception() +// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] +// CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) +// CHECK-NEXT: call void @__cxa_end_catch() +// CHECK-NEXT: br label +// CHECK: load i8** [[CAUGHTEXNVAR]] +// CHECK-NEXT: call i8* @__cxa_begin_catch +// CHECK-NEXT: call void @__cxa_end_catch + catch (...) { + } +// CHECK: ret i32 0 + return 0; + } +} + +// Ordering of destructors in a catch handler. +namespace test8 { + struct A { A(const A&); ~A(); }; + void bar(); + + // CHECK: define void @_ZN5test83fooEv() + void foo() { + try { + // CHECK: invoke void @_ZN5test83barEv() + bar(); + } catch (A a) { + // CHECK: call i8* @__cxa_get_exception_ptr + // CHECK-NEXT: bitcast + // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_( + // CHECK: call i8* @__cxa_begin_catch + // CHECK-NEXT: invoke void @_ZN5test81AD1Ev( + + // CHECK: call void @__cxa_end_catch() + // CHECK-NEXT: load + // CHECK-NEXT: switch + + // CHECK: ret void + } + } +} + +// Constructor function-try-block must rethrow on fallthrough. +// rdar://problem/7696603 +namespace test9 { + void opaque(); + + struct A { A(); }; + + // CHECK: define void @_ZN5test91AC1Ev + // CHECK: call void @_ZN5test91AC2Ev + // CHECK-NEXT: ret void + + // CHECK: define void @_ZN5test91AC2Ev( + A::A() try { + // CHECK: invoke void @_ZN5test96opaqueEv() + opaque(); + } catch (int x) { + // CHECK: call i8* @__cxa_begin_catch + // CHECK: invoke void @_ZN5test96opaqueEv() + // CHECK: invoke void @__cxa_rethrow() + opaque(); + } + + // landing pad from first call to invoke + // CHECK: call i8* @llvm.eh.exception + // 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) +} |