]> granicus.if.org Git - clang/commitdiff
SEH: Don't jump to an unreachable continuation block
authorReid Kleckner <reid@kleckner.net>
Fri, 30 Jan 2015 22:16:45 +0000 (22:16 +0000)
committerReid Kleckner <reid@kleckner.net>
Fri, 30 Jan 2015 22:16:45 +0000 (22:16 +0000)
If both the __try and __except blocks do not return, we want to delete
the continuation block as unreachable instead.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@227627 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGException.cpp
test/CodeGen/exceptions-seh.c

index 68764e9260629c78885407442e88cf4a3f20ec5e..9f886ebb13a43a56849944ed8d7cdd06ec034557 100644 (file)
@@ -1899,7 +1899,8 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {
   // Emit the __except body.
   EmitStmt(Except->getBlock());
 
-  Builder.CreateBr(ContBB);
+  if (HaveInsertPoint())
+    Builder.CreateBr(ContBB);
 
   EmitBlock(ContBB);
 }
index bba5eac36c51b4916bcbdf7ae282a486844aefbd..07b43c6f108ffd14d7a483a53279ffce51fc3686 100644 (file)
@@ -38,7 +38,7 @@ int safe_div(int numerator, int denominator, int *res) {
 void j(void);
 
 // FIXME: Implement local variable captures in filter expressions.
-int filter_expr_capture() {
+int filter_expr_capture(void) {
   int r = 42;
   __try {
     j();
@@ -65,7 +65,7 @@ int filter_expr_capture() {
 // FIXMECHECK: store i32 -1, i32* %{{.*}}
 // CHECK: ret i32 -1
 
-int nested_try() {
+int nested_try(void) {
   int r = 42;
   __try {
     __try {
@@ -121,7 +121,7 @@ int nested_try() {
 // FIXME: This lowering of __finally can't actually work, it will have to
 // change.
 static unsigned g = 0;
-void basic_finally() {
+void basic_finally(void) {
   ++g;
   __try {
     j();
@@ -150,3 +150,27 @@ void basic_finally() {
 // CHECK: add i32 %{{.*}}, -1
 // CHECK: store i32 %{{.*}}, i32* @g
 // CHECK: resume
+
+int returns_int(void);
+int except_return(void) {
+  __try {
+    return returns_int();
+  } __except(1) {
+    return 42;
+  }
+}
+// CHECK-LABEL: define i32 @except_return()
+// CHECK: %[[tmp:[^ ]*]] = invoke i32 @returns_int()
+// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+//
+// CHECK: [[cont]]
+// CHECK: store i32 %[[tmp]], i32* %[[rv:[^ ]*]]
+// CHECK: br label %[[retbb:[^ ]*]]
+//
+// CHECK: [[lpad]]
+// CHECK: store i32 42, i32* %[[rv]]
+// CHECK: br label %[[retbb]]
+//
+// CHECK: [[retbb]]
+// CHECK: %[[r:[^ ]*]] = load i32* %[[rv]]
+// CHECK: ret i32 %[[r]]