diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-03-03 19:21:04 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-03-03 19:21:04 +0000 |
commit | 46aa51e375f51b15badc7c7b531c9cb951a15801 (patch) | |
tree | 185759930aa69f75f5a944384ee16a6e44fdf1ac /test/CodeGenCXX/microsoft-abi-eh-catch.cpp | |
parent | 5b3adcabd4a55fe15926e18f62e79d438ff76156 (diff) |
Split catch IRgen into ItaniumCXXABI and MicrosoftCXXABI
Use llvm.eh.begincatch for Microsoft-style catches.
This moves lots of CGException code into ItaniumCXXABI. Sorry for the
blame pain.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231105 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/microsoft-abi-eh-catch.cpp')
-rw-r--r-- | test/CodeGenCXX/microsoft-abi-eh-catch.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp new file mode 100644 index 0000000000..f0e2033451 --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc -mconstructor-aliases -fexceptions -fcxx-exceptions | FileCheck -check-prefix WIN64 %s + +extern "C" void might_throw(); + +// Simplify the generated IR with noexcept. +extern "C" void recover() noexcept(true); +extern "C" void handle_exception(void *e) noexcept(true); + +extern "C" void catch_all() { + try { + might_throw(); + } catch (...) { + recover(); + } +} + +// WIN64-LABEL: define void @catch_all() +// WIN64: invoke void @might_throw() +// WIN64-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] +// +// WIN64: [[cont]] +// WIN64: br label %[[ret:[^ ]*]] +// +// WIN64: [[lpad]] +// WIN64: landingpad { i8*, i32 } +// WIN64-NEXT: catch i8* null +// WIN64: call void @llvm.eh.begincatch(i8* %{{[^,]*}}, i8* null) +// WIN64: call void @recover() +// WIN64: call void @llvm.eh.endcatch() +// WIN64: br label %[[ret]] +// +// WIN64: [[ret]] +// WIN64: ret void + +extern "C" void catch_int() { + try { + might_throw(); + } catch (int e) { + handle_exception(&e); + } +} + +// WIN64-LABEL: define void @catch_int() +// WIN64: landingpad { i8*, i32 } +// WIN64: %[[e_i8:[^ ]*]] = bitcast i32* %[[e_addr:[^ ]*]] to i8* +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* %[[e_i8]]) +// WIN64: %[[e_i8:[^ ]*]] = bitcast i32* %[[e_addr]] to i8* +// WIN64: call void @handle_exception(i8* %[[e_i8]]) +// WIN64: call void @llvm.eh.endcatch() + +struct A { + A(); + A(const A &o); + ~A(); + int a; +}; + +struct B : A { + B(); + B(const B &o); + ~B(); + int b; +}; + +extern "C" void catch_a_byval() { + try { + might_throw(); + } catch (A e) { + handle_exception(&e); + } +} + +// WIN64-LABEL: define void @catch_a_byval() +// WIN64: %[[e_addr:[^ ]*]] = alloca %struct.A +// WIN64: landingpad { i8*, i32 } +// WIN64: %[[e_i8:[^ ]*]] = bitcast %struct.A* %[[e_addr]] to i8* +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* %[[e_i8]]) +// WIN64: %[[e_i8:[^ ]*]] = bitcast %struct.A* %[[e_addr]] to i8* +// WIN64: call void @handle_exception(i8* %[[e_i8]]) +// WIN64: call void @llvm.eh.endcatch() + +extern "C" void catch_a_ref() { + try { + might_throw(); + } catch (A &e) { + handle_exception(&e); + } +} + +// WIN64-LABEL: define void @catch_a_ref() +// WIN64: %[[e_addr:[^ ]*]] = alloca %struct.A* +// WIN64: landingpad { i8*, i32 } +// WIN64: %[[e_i8:[^ ]*]] = bitcast %struct.A** %[[e_addr]] to i8* +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* %[[e_i8]]) +// WIN64: %[[eptr:[^ ]*]] = load %struct.A*, %struct.A** %[[e_addr]] +// WIN64: %[[eptr_i8:[^ ]*]] = bitcast %struct.A* %[[eptr]] to i8* +// WIN64: call void @handle_exception(i8* %[[eptr_i8]]) +// WIN64: call void @llvm.eh.endcatch() |