diff options
Diffstat (limited to 'test/CodeGenCXX/exceptions.cpp')
-rw-r--r-- | test/CodeGenCXX/exceptions.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp index 079c1e5..8c20c9e 100644 --- a/test/CodeGenCXX/exceptions.cpp +++ b/test/CodeGenCXX/exceptions.cpp @@ -414,3 +414,39 @@ namespace test9 { // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]]) } + +// In a destructor with a function-try-block, a return statement in a +// catch handler behaves differently from running off the end of the +// catch handler. PR13102. +namespace test10 { + extern void cleanup(); + extern bool suppress; + + struct A { ~A(); }; + A::~A() try { cleanup(); } catch (...) { return; } + // CHECK: define void @_ZN6test101AD1Ev( + // CHECK: invoke void @_ZN6test107cleanupEv() + // CHECK-NOT: rethrow + // CHECK: ret void + + struct B { ~B(); }; + B::~B() try { cleanup(); } catch (...) {} + // CHECK: define void @_ZN6test101BD1Ev( + // CHECK: invoke void @_ZN6test107cleanupEv() + // CHECK: call i8* @__cxa_begin_catch + // CHECK-NEXT: invoke void @__cxa_rethrow() + // CHECK: unreachable + + struct C { ~C(); }; + C::~C() try { cleanup(); } catch (...) { if (suppress) return; } + // CHECK: define void @_ZN6test101CD1Ev( + // CHECK: invoke void @_ZN6test107cleanupEv() + // CHECK: call i8* @__cxa_begin_catch + // CHECK-NEXT: load i8* @_ZN6test108suppressE, align 1 + // CHECK-NEXT: trunc + // CHECK-NEXT: br i1 + // CHECK: call void @__cxa_end_catch() + // CHECK-NEXT: br label + // CHECK: invoke void @__cxa_rethrow() + // CHECK: unreachable +} |