1 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s 2 3 int f(int); 4 5 void test_catch() { 6 try { 7 f(1); 8 } catch (int) { 9 f(2); 10 } catch (double) { 11 f(3); 12 } 13 } 14 15 // CHECK-LABEL: define void @"\01?test_catch@@YAXXZ"( 16 // CHECK: invoke i32 @"\01?f@@YAHH@Z"(i32 1) 17 // CHECK: to label %[[NORMAL:.*]] unwind label %[[CATCHSWITCH:.*]] 18 19 // CHECK: [[CATCHSWITCH]] 20 // CHECK: %[[CATCHSWITCHPAD:.*]] = catchswitch within none [label %[[CATCH_INT:.*]], label %[[CATCH_DOUBLE:.*]]] unwind to caller 21 22 // CHECK: [[CATCH_INT]] 23 // CHECK: %[[CATCHPAD_INT:.*]] = catchpad within %[[CATCHSWITCHPAD]] [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] 24 // CHECK: call i32 @"\01?f@@YAHH@Z"(i32 2) 25 // CHECK: catchret from %[[CATCHPAD_INT]] to label %[[LEAVE_INT_CATCH:.*]] 26 27 // CHECK: [[LEAVE_INT_CATCH]] 28 // CHECK: br label %[[LEAVE_FUNC:.*]] 29 30 // CHECK: [[LEAVE_FUNC]] 31 // CHECK: ret void 32 33 // CHECK: [[CATCH_DOUBLE]] 34 // CHECK: %[[CATCHPAD_DOUBLE:.*]] = catchpad within %[[CATCHSWITCHPAD]] [%rtti.TypeDescriptor2* @"\01??_R0N@8", i32 0, i8* null] 35 // CHECK: call i32 @"\01?f@@YAHH@Z"(i32 3) 36 // CHECK: catchret from %[[CATCHPAD_DOUBLE]] to label %[[LEAVE_DOUBLE_CATCH:.*]] 37 38 // CHECK: [[LEAVE_DOUBLE_CATCH]] 39 // CHECK: br label %[[LEAVE_FUNC]] 40 41 // CHECK: [[NORMAL]] 42 // CHECK: br label %[[LEAVE_FUNC]] 43 44 struct Cleanup { 45 ~Cleanup() { f(-1); } 46 }; 47 48 void test_cleanup() { 49 Cleanup C; 50 f(1); 51 } 52 53 // CHECK-LABEL: define {{.*}} @"\01?test_cleanup@@YAXXZ"( 54 // CHECK: invoke i32 @"\01?f@@YAHH@Z"(i32 1) 55 // CHECK: to label %[[LEAVE_FUNC:.*]] unwind label %[[CLEANUP:.*]] 56 57 // CHECK: [[LEAVE_FUNC]] 58 // CHECK: call x86_thiscallcc void @"\01??_DCleanup@@QAE@XZ"( 59 // CHECK: ret void 60 61 // CHECK: [[CLEANUP]] 62 // CHECK: %[[CLEANUPPAD:.*]] = cleanuppad within none [] 63 // CHECK: call x86_thiscallcc void @"\01??_DCleanup@@QAE@XZ"( 64 // CHECK: cleanupret from %[[CLEANUPPAD]] unwind to caller 65 66 67 // CHECK-LABEL: define {{.*}} void @"\01??1Cleanup@@QAE@XZ"( 68 // CHECK: invoke i32 @"\01?f@@YAHH@Z"(i32 -1) 69 // CHECK: to label %[[LEAVE_FUNC:.*]] unwind label %[[TERMINATE:.*]] 70 71 // CHECK: [[LEAVE_FUNC]] 72 // CHECK: ret void 73 74 // CHECK: [[TERMINATE]] 75 // CHECK: %[[CLEANUPPAD:.*]] = cleanuppad within none [] 76 // CHECK-NEXT: call void @"\01?terminate@@YAXXZ"() {{.*}} [ "funclet"(token %[[CLEANUPPAD]]) ] 77 78