llvm-project/clang/test/CodeGenCXX/exceptions-cxx-new.cpp
David Majnemer feeefb214d [MS ABI] Don't rely on terminatepad
We'd like to remove support for terminatepad from LLVM.  To do this, we
need to move Clang off of it first.  The intent behind terminatepad was
to carefully model exception specifications for the MSVC personality.

However, we don't support exception specifications for the MSVC
personality and neither does MSVC.  Instead, MSVC supports
all-or-nothing exception specifications.  We can model this limited
usage using cleanuppads which call std::terminate.

Differential Revision: http://reviews.llvm.org/D15478

llvm-svn: 255521
2015-12-14 18:34:18 +00:00

78 lines
2.3 KiB
C++

// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -fexceptions -fcxx-exceptions -fnew-ms-eh -emit-llvm -o - -std=c++11 | FileCheck %s
int f(int);
void test_catch() {
try {
f(1);
} catch (int) {
f(2);
} catch (double) {
f(3);
}
}
// CHECK-LABEL: define void @"\01?test_catch@@YAXXZ"(
// CHECK: invoke i32 @"\01?f@@YAHH@Z"(i32 1)
// CHECK: to label %[[NORMAL:.*]] unwind label %[[CATCHSWITCH:.*]]
// CHECK: [[CATCHSWITCH]]
// CHECK: %[[CATCHSWITCHPAD:.*]] = catchswitch within none [label %[[CATCH_INT:.*]], label %[[CATCH_DOUBLE:.*]]] unwind to caller
// CHECK: [[CATCH_INT]]
// CHECK: %[[CATCHPAD_INT:.*]] = catchpad within %[[CATCHSWITCHPAD]] [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
// CHECK: call i32 @"\01?f@@YAHH@Z"(i32 2)
// CHECK: catchret from %[[CATCHPAD_INT]] to label %[[LEAVE_INT_CATCH:.*]]
// CHECK: [[LEAVE_INT_CATCH]]
// CHECK: br label %[[LEAVE_FUNC:.*]]
// CHECK: [[LEAVE_FUNC]]
// CHECK: ret void
// CHECK: [[CATCH_DOUBLE]]
// CHECK: %[[CATCHPAD_DOUBLE:.*]] = catchpad within %[[CATCHSWITCHPAD]] [%rtti.TypeDescriptor2* @"\01??_R0N@8", i32 0, i8* null]
// CHECK: call i32 @"\01?f@@YAHH@Z"(i32 3)
// CHECK: catchret from %[[CATCHPAD_DOUBLE]] to label %[[LEAVE_DOUBLE_CATCH:.*]]
// CHECK: [[LEAVE_DOUBLE_CATCH]]
// CHECK: br label %[[LEAVE_FUNC]]
// CHECK: [[NORMAL]]
// CHECK: br label %[[LEAVE_FUNC]]
struct Cleanup {
~Cleanup() { f(-1); }
};
void test_cleanup() {
Cleanup C;
f(1);
}
// CHECK-LABEL: define {{.*}} @"\01?test_cleanup@@YAXXZ"(
// CHECK: invoke i32 @"\01?f@@YAHH@Z"(i32 1)
// CHECK: to label %[[LEAVE_FUNC:.*]] unwind label %[[CLEANUP:.*]]
// CHECK: [[LEAVE_FUNC]]
// CHECK: call x86_thiscallcc void @"\01??_DCleanup@@QAE@XZ"(
// CHECK: ret void
// CHECK: [[CLEANUP]]
// CHECK: %[[CLEANUPPAD:.*]] = cleanuppad within none []
// CHECK: call x86_thiscallcc void @"\01??_DCleanup@@QAE@XZ"(
// CHECK: cleanupret from %[[CLEANUPPAD]] unwind to caller
// CHECK-LABEL: define {{.*}} void @"\01??1Cleanup@@QAE@XZ"(
// CHECK: invoke i32 @"\01?f@@YAHH@Z"(i32 -1)
// CHECK: to label %[[LEAVE_FUNC:.*]] unwind label %[[TERMINATE:.*]]
// CHECK: [[LEAVE_FUNC]]
// CHECK: ret void
// CHECK: [[TERMINATE]]
// CHECK: cleanuppad within none []
// CHECK-NEXT: call void @"\01?terminate@@YAXXZ"()