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 | 11ca834bef952ee84d61b0e4bd3045077095f280 (patch) | |
tree | f514413543a35b9c0571bd67e2c0060ba81949ab /clang/test/CodeGenCXX/exceptions-seh.cpp | |
parent | 765fcc0d5b8f7eafae0898ccde4075eea6295d70 (diff) | |
download | bcm5719-llvm-11ca834bef952ee84d61b0e4bd3045077095f280.tar.gz bcm5719-llvm-11ca834bef952ee84d61b0e4bd3045077095f280.zip |
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.
llvm-svn: 228058
Diffstat (limited to 'clang/test/CodeGenCXX/exceptions-seh.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/exceptions-seh.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/exceptions-seh.cpp b/clang/test/CodeGenCXX/exceptions-seh.cpp new file mode 100644 index 00000000000..74b43a94f64 --- /dev/null +++ b/clang/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*) |