summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/exceptions-seh.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-02-03 22:52:35 +0000
committerReid Kleckner <reid@kleckner.net>2015-02-03 22:52:35 +0000
commit11ca834bef952ee84d61b0e4bd3045077095f280 (patch)
treef514413543a35b9c0571bd67e2c0060ba81949ab /clang/test/CodeGenCXX/exceptions-seh.cpp
parent765fcc0d5b8f7eafae0898ccde4075eea6295d70 (diff)
downloadbcm5719-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.cpp76
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*)
OpenPOWER on IntegriCloud