summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2015-04-13 20:03:03 +0000
committerNico Weber <nicolasweber@gmx.de>2015-04-13 20:03:03 +0000
commitf2a39a7b4e7028e4eefbffd6165a8e59d4df7c5d (patch)
treee9860c36153c06afef93abee62ef2921d37907e2 /clang/test
parentb31abb05fbbdbefecc15a5b9f3c054d8a2ce1a9f (diff)
downloadbcm5719-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.c227
-rw-r--r--clang/test/CodeGen/exceptions-seh-leave.c149
-rw-r--r--clang/test/CodeGen/exceptions-seh.c23
-rw-r--r--clang/test/CodeGenCXX/exceptions-seh.cpp44
-rw-r--r--clang/test/SemaCXX/switch-implicit-fallthrough.cpp6
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}}
OpenPOWER on IntegriCloud