2015-02-06 02:56:03 +08:00
|
|
|
// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
|
|
|
|
// RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \
|
|
|
|
// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH
|
|
|
|
// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
|
2015-02-11 08:00:21 +08:00
|
|
|
// RUN: -o - -mconstructor-aliases -O1 -disable-llvm-optzns | \
|
2015-02-06 02:56:03 +08:00
|
|
|
// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
// CXXEH-LABEL: define void @use_cxx()
|
|
|
|
// CXXEH: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
|
|
|
|
// CXXEH: invoke void @might_throw()
|
|
|
|
// CXXEH: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
|
|
|
|
//
|
|
|
|
// CXXEH: [[cont]]
|
|
|
|
// CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
|
|
|
|
// CXXEH: ret void
|
|
|
|
//
|
|
|
|
// CXXEH: [[lpad]]
|
|
|
|
// CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
|
|
|
|
// CXXEH-NEXT: cleanup
|
|
|
|
// CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
|
|
|
|
// CXXEH: br label %[[resume:[^ ]*]]
|
|
|
|
//
|
|
|
|
// CXXEH: [[resume]]
|
|
|
|
// CXXEH: resume
|
|
|
|
|
|
|
|
// NOCXX-LABEL: define void @use_cxx()
|
|
|
|
// NOCXX-NOT: invoke
|
|
|
|
// NOCXX: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
|
|
|
|
// NOCXX-NOT: invoke
|
|
|
|
// NOCXX: call void @might_throw()
|
|
|
|
// NOCXX-NOT: invoke
|
|
|
|
// NOCXX: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})
|
|
|
|
// NOCXX-NOT: invoke
|
|
|
|
// NOCXX: ret void
|
|
|
|
|
|
|
|
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()
|
2015-02-12 05:40:48 +08:00
|
|
|
// CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]]
|
2015-02-06 02:56:03 +08:00
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
|
|
|
|
// CXXEH-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()
|
|
|
|
// CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
|
|
|
|
|
|
|
|
// NOCXX-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()
|
|
|
|
// NOCXX-NOT: invoke
|
|
|
|
// NOCXX: ret void
|
|
|
|
|
|
|
|
// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this)
|
2015-02-12 05:40:48 +08:00
|
|
|
// CHECK: invoke void @might_throw() #[[NOINLINE]]
|
2015-02-06 02:56:03 +08:00
|
|
|
// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
|
2015-02-12 05:40:48 +08:00
|
|
|
|
|
|
|
// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }
|