diff options
author | Nico Weber <nicolasweber@gmx.de> | 2015-04-13 20:03:03 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2015-04-13 20:03:03 +0000 |
commit | f2a39a7b4e7028e4eefbffd6165a8e59d4df7c5d (patch) | |
tree | e9860c36153c06afef93abee62ef2921d37907e2 /clang/test | |
parent | b31abb05fbbdbefecc15a5b9f3c054d8a2ce1a9f (diff) | |
download | bcm5719-llvm-f2a39a7b4e7028e4eefbffd6165a8e59d4df7c5d.tar.gz bcm5719-llvm-f2a39a7b4e7028e4eefbffd6165a8e59d4df7c5d.zip |
Revert r234786, it contained a bunch of stuff I did not mean to commit.
llvm-svn: 234787
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGen/exceptions-seh-finally.c | 227 | ||||
-rw-r--r-- | clang/test/CodeGen/exceptions-seh-leave.c | 149 | ||||
-rw-r--r-- | clang/test/CodeGen/exceptions-seh.c | 23 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/exceptions-seh.cpp | 44 | ||||
-rw-r--r-- | clang/test/SemaCXX/switch-implicit-fallthrough.cpp | 6 |
5 files changed, 208 insertions, 241 deletions
diff --git a/clang/test/CodeGen/exceptions-seh-finally.c b/clang/test/CodeGen/exceptions-seh-finally.c index eeadf0d5ec5..a594aaac051 100644 --- a/clang/test/CodeGen/exceptions-seh-finally.c +++ b/clang/test/CodeGen/exceptions-seh-finally.c @@ -17,30 +17,20 @@ void basic_finally(void) { // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK: call void @cleanup() -// CHECK: load i8, i8* %[[abnormal]] -// CHECK: icmp eq -// CHECK: br i1 %{{.*}}, label %[[finallycont:[^ ]*]], label %[[resumecont:[^ ]*]] -// -// CHECK: [[finallycont]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i1 zeroext false, i8* %[[fp]]) // CHECK-NEXT: ret void // // CHECK: [[lpad]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK: br label %[[finally]] -// -// CHECK: [[resumecont]] -// CHECK: br label %[[ehresume:[^ ]*]] -// -// CHECK: [[ehresume]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i1 zeroext true, i8* %[[fp]]) // CHECK: resume { i8*, i32 } +// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: call void @cleanup() + // Mostly check that we don't double emit 'r' which would crash. void decl_in_finally(void) { __try { @@ -67,10 +57,11 @@ l: // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@label_in_finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void + +// CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) // CHECK: br label %[[l:[^ ]*]] // // CHECK: [[l]] @@ -93,32 +84,22 @@ void use_abnormal_termination(void) { // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK: load i8, i8* %[[abnormal]] -// CHECK: zext i8 %{{.*}} to i32 -// CHECK: store i32 %{{.*}}, i32* @crashed -// CHECK: load i8, i8* %[[abnormal]] -// CHECK: icmp eq -// CHECK: br i1 %{{.*}}, label %[[finallycont:[^ ]*]], label %[[resumecont:[^ ]*]] -// -// CHECK: [[finallycont]] -// CHECK-NEXT: ret void +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void // // CHECK: [[lpad]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK: br label %[[finally]] -// -// CHECK: [[resumecont]] -// CHECK: br label %[[ehresume:[^ ]*]] -// -// CHECK: [[ehresume]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"(i1 zeroext true, i8* %[[fp]]) // CHECK: resume { i8*, i32 } +// CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: %[[abnormal_zext:[^ ]*]] = zext i1 %abnormal_termination to i32 +// CHECK: store i32 %[[abnormal_zext]], i32* @crashed +// CHECK-NEXT: ret void + void noreturn_noop_finally() { __try { __noop(); @@ -128,12 +109,13 @@ void noreturn_noop_finally() { } // CHECK-LABEL: define void @noreturn_noop_finally() -// CHECK: store i8 0, i8* % -// CHECK: br label %[[finally:[^ ]*]] -// CHECK: [[finally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@noreturn_noop_finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void + +// CHECK: define internal void @"\01?fin$0@0@noreturn_noop_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) // CHECK: call void @abort() -// CHECK-NEXT: unreachable -// CHECK-NOT: load +// CHECK: unreachable void noreturn_finally() { __try { @@ -148,18 +130,20 @@ void noreturn_finally() { // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[cont]] -// CHECK: store i8 0, i8* % -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK: call void @abort() -// CHECK-NEXT: unreachable +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void // // CHECK: [[lpad]] // CHECK: landingpad // CHECK-NEXT: cleanup -// CHECK: store i8 1, i8* % -// CHECK: br label %[[finally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"(i1 zeroext true, i8* %[[fp]]) +// CHECK: resume { i8*, i32 } + +// CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: call void @abort() +// CHECK: unreachable int finally_with_return() { __try { @@ -168,15 +152,15 @@ int finally_with_return() { } } // CHECK-LABEL: define i32 @finally_with_return() -// CHECK: store i8 0, i8* % -// CHECK-NEXT: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK-NEXT: br label %[[finallycont:[^ ]*]] -// -// CHECK: [[finallycont]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@finally_with_return@@"(i1 zeroext false, i8* %[[fp]]) // CHECK-NEXT: ret i32 42 +// CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK-NOT: br i1 +// CHECK-NOT: br label +// CHECK: ret void + int nested___finally___finally() { __try { __try { @@ -188,38 +172,28 @@ int nested___finally___finally() { } return 0; } + // CHECK-LABEL: define i32 @nested___finally___finally -// CHECK: store i8 0, i8* % -// CHECK-NEXT: br label %[[finally:[^ ]*]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // -// CHECK: [[finally]] -// CHECK-NEXT: store i32 1, i32* % -// CHECK-NEXT: store i32 1, i32* % -// CHECK-NEXT: br label %[[cleanup:[^ ]*]] +// CHECK: [[outercont]] +// CHECK-NEXT: %[[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: ret i32 0 // -// The finally's unreachable continuation block: -// CHECK: store i32 0, i32* % -// CHECK-NEXT: br label %[[cleanup]] -// -// CHECK: [[cleanup]] -// CHECK-NEXT: store i8 0, i8* % -// CHECK-NEXT: br label %[[outerfinally:[^ ]*]] -// -// CHECK: [[outerfinally]] -// CHECK-NEXT: br label %[[finallycont:[^ ]*]] -// -// CHECK: [[finallycont]] -// CHECK-NEXT: %[[dest:[^ ]*]] = load i32, i32* % -// CHECK-NEXT: switch i32 %[[dest]] -// CHECK-NEXT: i32 0, label %[[cleanupcont:[^ ]*]] -// -// CHECK: [[cleanupcont]] -// CHECK-NEXT: store i32 0, i32* % -// CHECK-NEXT: br label %[[return:[^ ]*]] -// -// CHECK: [[return]] -// CHECK-NEXT: %[[reg:[^ ]*]] = load i32, i32* % -// CHECK-NEXT: ret i32 %[[reg]] +// CHECK: [[lpad]] +// CHECK-NEXT: landingpad +// CHECK-NEXT: cleanup +// 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-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: ret void + +// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: unreachable int nested___finally___finally_with_eh_edge() { __try { @@ -234,58 +208,35 @@ int nested___finally___finally_with_eh_edge() { return 912; } // CHECK-LABEL: define i32 @nested___finally___finally_with_eh_edge -// CHECK: invoke void @might_crash() #3 -// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad:[^ ]*]] -// -// CHECK: [[invokecont]] -// CHECK-NEXT: store i8 0, i8* %[[abnormal:[^ ]*]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] - -// CHECK: [[finally]] -// CHECK-NEXT: store i32 899, i32* % -// CHECK-NEXT: store i32 1, i32* % -// CHECK-NEXT: br label %[[cleanup:[^ ]*]] -// -// The inner finally's unreachable continuation block: -// CHECK: store i32 0, i32* % -// CHECK-NEXT: br label %[[cleanup]] -// -// CHECK: [[cleanup]] -// CHECK-NEXT: store i8 0, i8* % -// 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: %[[dest:[^ ]*]] = load i32, i32* % -// CHECK-NEXT: switch i32 %[[dest]] -// CHECK-NEXT: i32 0, label %[[cleanupcont:[^ ]*]] +// CHECK: invoke void @might_crash() +// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]] // -// CHECK: [[cleanupcont]] -// CHECK-NEXT: store i32 912, i32* % -// CHECK-NEXT: br label %[[return:[^ ]*]] +// [[invokecont]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]] // +// CHECK: [[outercont]] +// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK-NEXT: ret i32 912 // -// CHECK: [[lpad]] +// CHECK: [[lpad1]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK: br label %[[finally]] -// -// The inner finally's unreachable resume block: -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK-NEXT: br label %[[outerfinally]] +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext true, i8* %[[fp]]) +// CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2]] // -// CHECK: [[finallyresume]] -// CHECK-NEXT: br label %[[ehresume:[^ ]*]] -// -// CHECK: [[return]] -// CHECK-NEXT: %[[reg:[^ ]*]] = load i32, i32* % -// CHECK-NEXT: ret i32 %[[reg]] -// -// The ehresume block, not reachable either. -// CHECK: [[ehresume]] +// CHECK: [[lpad2]] +// CHECK-NEXT: landingpad +// CHECK-NEXT: cleanup +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext true, i8* %[[fp]]) // CHECK: resume + +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: ret void + +// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: unreachable diff --git a/clang/test/CodeGen/exceptions-seh-leave.c b/clang/test/CodeGen/exceptions-seh-leave.c index 0d38439c9b0..793501a9fe5 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 g(void); ////////////////////////////////////////////////////////////////////////////// // __leave with __except @@ -38,7 +38,7 @@ int __leave_with___except() { return 1; } // CHECK-LABEL: define i32 @__leave_with___except() -// CHECK: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK: invoke void @g() // 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: store i8 0, i8* % -// CHECK-NEXT: br label % +// 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]]) // __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: store i8 0, i8* % -// CHECK-NEXT: br label % +// 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]]) // 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 bitcast (void (...)* @g to void ()*)() +// CHECK: invoke void @g() // 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: store i8 0, i8* % -// CHECK-NEXT: br label % +// 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]]) ////////////////////////////////////////////////////////////////////////////// @@ -142,45 +142,37 @@ 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 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-LABEL: invoke void @g() +// CHECK-NEXT: to label %[[g1_cont1:.*]] unwind label %[[g1_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: [[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:.*]] -// Unused __finally continuation block +// CHECK: [[fin_cont]] // CHECK: store i32 51, i32* % -// CHECK-NEXT: br label %[[tryleave]] - -// CHECK: [[tryleave]] // CHECK-NEXT: br label %[[trycont:[^ ]*]] // CHECK: [[g1_lpad]] -// CHECK: store i8 1, i8* % -// CHECK-NEXT: br label %[[finally]] +// 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: [[g2_lpad]] -// CHECK-NOT: %[[abnormal]] -// CHECK: br label %[[except:[^ ]*]] - -// CHECK: [[except]] -// CHECK-NEXT: br label %[[trycont]] +// CHECK: 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 { @@ -202,7 +194,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 bitcast (void (...)* @g to void ()*)() +// CHECK-LABEL: invoke void @g() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] @@ -213,7 +205,7 @@ int nested___except___except() { // CHECK: br label %[[except:[^ ]*]] // CHECK: [[except]] -// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() #3 +// CHECK-NEXT: invoke void @g() // CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] // CHECK: [[g2_cont]] @@ -256,7 +248,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 bitcast (void (...)* @g to void ()*)() +// CHECK-LABEL: invoke void @g() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] @@ -266,7 +258,7 @@ int nested___finally___except() { // CHECK: br label %[[except:[^ ]*]] // CHECK: [[except]] -// CHECK-NEXT: invoke void bitcast (void (...)* @g to void ()*)() +// CHECK-NEXT: invoke void @g() // CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] // CHECK: [[g2_cont]] @@ -274,31 +266,25 @@ int nested___finally___except() { // CHECK-NOT: 23 // CHECK: [[g2_lpad]] -// CHECK: store i8 1, i8* %[[abnormal:[^ ]*]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] +// 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: [[trycont]] // CHECK: store i32 51, i32* % // CHECK-NEXT: br label %[[tryleave]] // CHECK: [[tryleave]] -// 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: %[[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: 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 { @@ -320,51 +306,44 @@ 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 bitcast (void (...)* @g to void ()*)() +// CHECK-LABEL: invoke void @g() // CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]] // CHECK: [[g1_cont]] // CHECK: store i32 16, i32* %[[myres:[^ ]*]], -// 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: %[[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:.*]] -// There's an unreachable block for the skipped `myres = 51`. +// CHECK: [[finally_cont]] // CHECK: store i32 51, i32* %[[myres]] -// 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: %[[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: ret i32 1 // CHECK: [[g1_lpad]] -// CHECK: store i8 1, i8* %[[abnormal]] -// CHECK-NEXT: br label %[[finally:[^ ]*]] +// 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: [[g2_lpad]] -// CHECK: br label %[[ehcleanup:[^ ]*]] +// CHECK-NEXT: landingpad +// CHECK-NEXT: cleanup +// CHECK: br label %[[ehcleanup:.*]] + +// CHECK: [[finally_cont2]] +// CHECK: br label %[[ehcleanup]] // CHECK: [[ehcleanup]] -// CHECK-NEXT: store i8 1, i8* %[[abnormal]] -// CHECK-NEXT: br label %[[outerfinally]] +// 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: [[finallyresume]] -// CHECK-NEXT: br label %[[ehresume:[^ ]*]] +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: ret void -// CHECK: [[ehresume]] -// CHECK: resume +// 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 diff --git a/clang/test/CodeGen/exceptions-seh.c b/clang/test/CodeGen/exceptions-seh.c index 2d9d4b1f018..9a273ced567 100644 --- a/clang/test/CodeGen/exceptions-seh.c +++ b/clang/test/CodeGen/exceptions-seh.c @@ -118,8 +118,6 @@ int nested_try(void) { // CHECK: [[inner_try_cont]] // CHECK: br label %[[outer_try_cont]] -// FIXME: This lowering of __finally can't actually work, it will have to -// change. static unsigned g = 0; void basic_finally(void) { ++g; @@ -138,24 +136,23 @@ void basic_finally(void) { // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[cont]] -// CHECK: br label %[[finally:[^ ]*]] -// -// CHECK: [[finally]] -// CHECK: load i32, i32* @g -// CHECK: add i32 %{{.*}}, -1 -// CHECK: store i32 %{{.*}}, i32* @g -// CHECK: icmp eq -// CHECK: br i1 %{{.*}}, label -// +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i1 zeroext false, i8* %[[fp]]) // CHECK: ret void // // CHECK: [[lpad]] // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) // CHECK-NEXT: cleanup -// CHECK: br label %[[finally]] -// +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i1 zeroext true, i8* %[[fp]]) // CHECK: resume +// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) +// CHECK: load i32, i32* @g, align 4 +// CHECK: add i32 %{{.*}}, -1 +// CHECK: store i32 %{{.*}}, i32* @g, align 4 +// CHECK: ret void + int returns_int(void); int except_return(void) { __try { diff --git a/clang/test/CodeGenCXX/exceptions-seh.cpp b/clang/test/CodeGenCXX/exceptions-seh.cpp index 5f93cb1be3f..cb5f6dfad90 100644 --- a/clang/test/CodeGenCXX/exceptions-seh.cpp +++ b/clang/test/CodeGenCXX/exceptions-seh.cpp @@ -5,6 +5,7 @@ // RUN: -o - -mconstructor-aliases -O1 -disable-llvm-optzns | \ // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX +extern "C" unsigned long _exception_code(); extern "C" void might_throw(); struct HasCleanup { @@ -95,4 +96,47 @@ void use_seh_in_lambda() { // CHECK: invoke void @might_throw() #[[NOINLINE]] // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +static int my_unique_global; + +extern "C" inline void use_seh_in_inline_func() { + __try { + might_throw(); + } __except(_exception_code() == 424242) { + } + __try { + might_throw(); + } __finally { + my_unique_global = 1234; + } +} + +void use_inline() { + use_seh_in_inline_func(); +} + +// CHECK-LABEL: define linkonce_odr void @use_seh_in_inline_func() #{{[0-9]+}} comdat { +// CHECK: invoke void @might_throw() +// +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_seh_in_inline_func@@" to i8*) +// +// CHECK: invoke void @might_throw() +// +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i1 zeroext false, i8* %[[fp]]) +// CHECK: ret void +// +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-NEXT: cleanup +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i1 zeroext true, i8* %[[fp]]) + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func) +// CHECK: icmp eq i32 %{{.*}}, 424242 +// CHECK: zext i1 %{{.*}} to i32 +// CHECK: ret i32 + +// CHECK-LABEL: define internal void @"\01?fin$0@0@use_seh_in_inline_func@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func) +// CHECK: store i32 1234, i32* @my_unique_global + // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} } diff --git a/clang/test/SemaCXX/switch-implicit-fallthrough.cpp b/clang/test/SemaCXX/switch-implicit-fallthrough.cpp index a547dc6d9f8..0bc43cdbd45 100644 --- a/clang/test/SemaCXX/switch-implicit-fallthrough.cpp +++ b/clang/test/SemaCXX/switch-implicit-fallthrough.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s + int fallthrough(int n) { switch (n / 10) { if (n - 1) { @@ -299,8 +300,3 @@ int fallthrough_targets(int n) { } return n; } - -[[clang::fallthrough]] int a; // expected-error {{'fallthrough' attribute only applies to empty statements}} -[[clang::fallthrough]] int f(); // expected-error {{'fallthrough' attribute only applies to empty statements}} -void g([[clang::fallthrough]] int p); // expected-error {{'fallthrough' attribute only applies to empty statements}} -struct [[clang::fallthrough]] S; // expected-error {{'fallthrough' attribute only applies to empty statements}} |