diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-02-03 22:52:35 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-02-03 22:52:35 +0000 |
commit | 41c5887917db2aba647714cfad1e675d6d93cd1e (patch) | |
tree | 0f9f73a1a7354c6b77b19d397c37c6d75d0443b5 /test/CodeGenCXX/exceptions-seh.cpp | |
parent | 1f6936185b95a45fedeff6267457b68aeeea1578 (diff) |
SEH: Track users of __try so we can pick a per-func EH personality
There are four major kinds of declarations that cause code generation:
- FunctionDecl (includes CXXMethodDecl etc)
- ObjCMethodDecl
- BlockDecl
- CapturedDecl
This patch tracks __try usage on FunctionDecls and diagnoses __try usage
in other decls. If someone wants to use __try from ObjC, they can use it
from a free function, since the ObjC code will need an ObjC-style EH
personality.
Eventually we will want to look through CapturedDecls and track SEH
usage on the parent FunctionDecl, if present.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228058 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/exceptions-seh.cpp')
-rw-r--r-- | test/CodeGenCXX/exceptions-seh.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp new file mode 100644 index 0000000000..74b43a94f6 --- /dev/null +++ b/test/CodeGenCXX/exceptions-seh.cpp @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm -o - -fcxx-exceptions -fexceptions -mconstructor-aliases | FileCheck %s + +extern "C" void might_throw(); + +struct HasCleanup { + HasCleanup(); + ~HasCleanup(); + int padding; +}; + +extern "C" void use_cxx() { + HasCleanup x; + might_throw(); +} + +// Make sure we use __CxxFrameHandler3 for C++ EH. + +// CHECK-LABEL: define void @use_cxx() +// CHECK: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) +// CHECK: invoke void @might_throw() +// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] +// +// CHECK: [[cont]] +// CHECK: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) +// CHECK: ret void +// +// CHECK: [[lpad]] +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) +// CHECK-NEXT: cleanup +// CHECK: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) +// CHECK: br label %[[resume:[^ ]*]] +// +// CHECK: [[resume]] +// CHECK: resume + +extern "C" void use_seh() { + __try { + might_throw(); + } __except(1) { + } +} + +// Make sure we use __C_specific_handler for SEH. + +// CHECK-LABEL: define void @use_seh() +// CHECK: invoke void @might_throw() +// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] +// +// CHECK: [[cont]] +// CHECK: br label %[[ret:[^ ]*]] +// +// CHECK: [[lpad]] +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-NEXT: catch i8* +// +// CHECK: br label %[[ret]] +// +// CHECK: [[ret]] +// CHECK: ret void + +void use_seh_in_lambda() { + ([]() { + __try { + might_throw(); + } __except(1) { + } + })(); + HasCleanup x; + might_throw(); +} + +// CHECK-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"() +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) + +// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this) +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) |