diff options
Diffstat (limited to 'clang/test/CodeGen/exceptions-seh-leave.c')
| -rw-r--r-- | clang/test/CodeGen/exceptions-seh-leave.c | 149 |
1 files changed, 85 insertions, 64 deletions
diff --git a/clang/test/CodeGen/exceptions-seh-leave.c b/clang/test/CodeGen/exceptions-seh-leave.c index 793501a9fe5..0d38439c9b0 100644 --- a/clang/test/CodeGen/exceptions-seh-leave.c +++ b/clang/test/CodeGen/exceptions-seh-leave.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s -void g(void); +void g(); ////////////////////////////////////////////////////////////////////////////// // __leave with __except @@ -38,7 +38,7 @@ int __leave_with___except() { return 1; } // CHECK-LABEL: define i32 @__leave_with___except() -// CHECK: invoke void @g() +// CHECK: invoke void bitcast (void (...)* @g to void ()*)() // CHECK-NEXT: to label %[[cont:.*]] unwind label %{{.*}} // For __excepts, instead of an explicit __try.__leave label, we could use // use invoke.cont as __leave jump target instead. However, not doing this @@ -74,8 +74,8 @@ int __leave_with___finally_simple() { // CHECK-NEXT: br label %[[tryleave:[^ ]*]] // CHECK-NOT: store i32 23 // CHECK: [[tryleave]] -// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally_simple@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: store i8 0, i8* % +// CHECK-NEXT: br label % // __finally block doesn't return, __finally.cont doesn't exist. int __leave_with___finally_noreturn() { @@ -94,8 +94,8 @@ int __leave_with___finally_noreturn() { // CHECK-NEXT: br label %[[tryleave:[^ ]*]] // CHECK-NOT: store i32 23 // CHECK: [[tryleave]] -// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally_noreturn@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: store i8 0, i8* % +// CHECK-NEXT: br label % // The "normal" case. int __leave_with___finally() { @@ -110,7 +110,7 @@ int __leave_with___finally() { return 1; } // CHECK-LABEL: define i32 @__leave_with___finally() -// CHECK: invoke void @g() +// CHECK: invoke void bitcast (void (...)* @g to void ()*)() // CHECK-NEXT: to label %[[cont:.*]] unwind label %{{.*}} // For __finally, there needs to be an explicit __try.__leave, because // abnormal.termination.slot needs to be set there. @@ -118,8 +118,8 @@ int __leave_with___finally() { // CHECK-NEXT: br label %[[tryleave:[^ ]*]] // CHECK-NOT: store i32 23 // CHECK: [[tryleave]] -// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: store i8 0, i8* % +// CHECK-NEXT: br label % ////////////////////////////////////////////////////////////////////////////// @@ -142,37 +142,45 @@ int nested___except___finally() { } return 1; } +// The order of basic blocks in the below doesn't matter. // CHECK-LABEL: define i32 @nested___except___finally() -// CHECK-LABEL: invoke void @g() -// CHECK-NEXT: to label %[[g1_cont1:.*]] unwind label %[[g1_lpad:.*]] +// CHECK-LABEL: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] + +// CHECK: [[g1_cont]] +// CHECK-NEXT: store i8 0, i8* %[[abnormal:[^ ]*]] +// CHECK-NEXT: br label %[[finally:[^ ]*]] -// CHECK: [[g1_cont1]] -// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: invoke void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext false, i8* %[[fp]]) -// CHECK-NEXT: to label %[[fin_cont:.*]] unwind label %[[g2_lpad:.*]] +// CHECK: [[finally]] +// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] + +// CHECK: [[g2_cont]] +// CHECK-NEXT: br label %[[tryleave:[^ ]*]] +// CHECK-NOT: store i32 23 -// CHECK: [[fin_cont]] +// Unused __finally continuation block // CHECK: store i32 51, i32* % +// CHECK-NEXT: br label %[[tryleave]] + +// CHECK: [[tryleave]] // CHECK-NEXT: br label %[[trycont:[^ ]*]] // CHECK: [[g1_lpad]] -// CHECK-NEXT: landingpad -// CHECK-NEXT: catch i8* null -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: invoke void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext true, i8* %[[fp]]) -// CHECK-NEXT: to label %[[g1_resume:.*]] unwind label %[[g2_lpad]] +// CHECK: store i8 1, i8* % +// CHECK-NEXT: br label %[[finally]] // CHECK: [[g2_lpad]] -// CHECK: br label %[[trycont]] +// CHECK-NOT: %[[abnormal]] +// CHECK: br label %[[except:[^ ]*]] + +// CHECK: [[except]] +// CHECK-NEXT: br label %[[trycont]] // CHECK: [[trycont]] // CHECK-NEXT: ret i32 1 -// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) -// CHECK: call void @g() -// CHECK: unreachable - int nested___except___except() { int myres = 0; __try { @@ -194,7 +202,7 @@ int nested___except___except() { // The order of basic blocks in the below doesn't matter. // CHECK-LABEL: define i32 @nested___except___except() -// CHECK-LABEL: invoke void @g() +// CHECK-LABEL: invoke void bitcast (void (...)* @g to void ()*)() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] @@ -205,7 +213,7 @@ int nested___except___except() { // CHECK: br label %[[except:[^ ]*]] // CHECK: [[except]] -// CHECK-NEXT: invoke void @g() +// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() #3 // CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] // CHECK: [[g2_cont]] @@ -248,7 +256,7 @@ int nested___finally___except() { // The order of basic blocks in the below doesn't matter. // CHECK-LABEL: define i32 @nested___finally___except() -// CHECK-LABEL: invoke void @g() +// CHECK-LABEL: invoke void bitcast (void (...)* @g to void ()*)() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] @@ -258,7 +266,7 @@ int nested___finally___except() { // CHECK: br label %[[except:[^ ]*]] // CHECK: [[except]] -// CHECK-NEXT: invoke void @g() +// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() // CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] // CHECK: [[g2_cont]] @@ -266,25 +274,31 @@ int nested___finally___except() { // CHECK-NOT: 23 // CHECK: [[g2_lpad]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext true, i8* %[[fp]]) -// CHECK-NEXT: br label %[[ehresume:[^ ]*]] +// CHECK: store i8 1, i8* %[[abnormal:[^ ]*]] +// CHECK-NEXT: br label %[[finally:[^ ]*]] // CHECK: [[trycont]] // CHECK: store i32 51, i32* % // CHECK-NEXT: br label %[[tryleave]] // CHECK: [[tryleave]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: store i8 0, i8* %[[abnormal]] +// CHECK-NEXT: br label %[[finally:[^ ]*]] + +// CHECK: [[finally]] +// CHECK-NEXT: %[[abnormallocal:[^ ]*]] = load i8, i8* %[[abnormal]] +// CHECK-NEXT: %[[reg:[^ ]*]] = icmp eq i8 %[[abnormallocal]], 0 +// CHECK-NEXT: br i1 %[[reg]], label %[[finallycont:[^ ]*]], label %[[finallyresume:[^ ]*]] + +// CHECK: [[finallycont]] // CHECK-NEXT: ret i32 1 +// CHECK: [[finallyresume]] +// CHECK-NEXT: br label %[[ehresume:[^ ]*]] + // CHECK: [[ehresume]] // CHECK: resume -// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) -// CHECK: ret void - int nested___finally___finally() { int myres = 0; __try { @@ -306,44 +320,51 @@ int nested___finally___finally() { // The order of basic blocks in the below doesn't matter. // CHECK-LABEL: define i32 @nested___finally___finally() -// CHECK-LABEL: invoke void @g() +// CHECK-LABEL: invoke void bitcast (void (...)* @g to void ()*)() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] // CHECK: store i32 16, i32* %[[myres:[^ ]*]], -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]]) -// CHECK-NEXT: to label %[[finally_cont:.*]] unwind label %[[g2_lpad:.*]] +// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]] +// CHECK-NEXT: br label %[[finally:[^ ]*]] + +// CHECK: [[finally]] +// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() #3 +// CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] + +// CHECK: [[g2_cont]] +// CHECK-NEXT: br label %[[tryleave:[^ ]*]] +// CHECK-NOT: store i32 23 -// CHECK: [[finally_cont]] +// There's an unreachable block for the skipped `myres = 51`. // CHECK: store i32 51, i32* %[[myres]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: br label %[[tryleave]] + +// CHECK: [[tryleave]] +// CHECK-NEXT: store i8 0, i8* %[[abnormal]] +// CHECK-NEXT: br label %[[outerfinally:[^ ]*]] + +// CHECK: [[outerfinally]] +// CHECK-NEXT: %[[abnormallocal:[^ ]*]] = load i8, i8* %[[abnormal]] +// CHECK-NEXT: %[[reg:[^ ]*]] = icmp eq i8 %[[abnormallocal]], 0 +// CHECK-NEXT: br i1 %[[reg]], label %[[finallycont:[^ ]*]], label %[[finallyresume:[^ ]*]] + +// CHECK: [[finallycont]] // CHECK-NEXT: ret i32 1 // CHECK: [[g1_lpad]] -// CHECK-NEXT: landingpad -// CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext true, i8* %[[fp]]) -// CHECK-NEXT: to label %[[finally_cont2:.*]] unwind label %[[g2_lpad]] +// CHECK: store i8 1, i8* %[[abnormal]] +// CHECK-NEXT: br label %[[finally:[^ ]*]] // CHECK: [[g2_lpad]] -// CHECK-NEXT: landingpad -// CHECK-NEXT: cleanup -// CHECK: br label %[[ehcleanup:.*]] - -// CHECK: [[finally_cont2]] -// CHECK: br label %[[ehcleanup]] +// CHECK: br label %[[ehcleanup:[^ ]*]] // CHECK: [[ehcleanup]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext true, i8* %[[fp]]) -// CHECK: resume +// CHECK-NEXT: store i8 1, i8* %[[abnormal]] +// CHECK-NEXT: br label %[[outerfinally]] -// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) -// CHECK: ret void +// CHECK: [[finallyresume]] +// CHECK-NEXT: br label %[[ehresume:[^ ]*]] -// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) -// CHECK: call void @g() -// CHECK: unreachable +// CHECK: [[ehresume]] +// CHECK: resume |

