<div dir="ltr">This seems to be breaking bots again:<div><a href="http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_check/2355/">http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_check/2355/</a></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 26, 2015 at 11:34 PM, Nico Weber <span dir="ltr"><<a href="mailto:nicolasweber@gmx.de" target="_blank">nicolasweber@gmx.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: nico<br>
Date: Thu Feb 26 16:34:33 2015<br>
New Revision: 230697<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=230697&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=230697&view=rev</a><br>
Log:<br>
Don't crash on leaving nested __finally blocks through an EH edge.<br>
<br>
The __finally emission block tries to be clever by removing unused continuation<br>
edges if there's an unconditional jump out of the __finally block. With<br>
exception edges, the EH continuation edge isn't always unused though and we'd<br>
crash in a few places.<br>
<br>
Just don't be clever. That makes the IR for __finally blocks a bit longer in<br>
some cases (hence small and behavior-preserving changes to existing tests), but<br>
it makes no difference in general and it fixes the last crash from PR22553.<br>
<br>
<a href="http://reviews.llvm.org/D7918" target="_blank">http://reviews.llvm.org/D7918</a><br>
<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CGException.cpp<br>
    cfe/trunk/test/CodeGen/exceptions-seh-finally.c<br>
    cfe/trunk/test/CodeGen/exceptions-seh-leave.c<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGException.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=230697&r1=230696&r2=230697&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=230697&r1=230696&r2=230697&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGException.cpp Thu Feb 26 16:34:33 2015<br>
@@ -<a href="tel:1684" value="+491684">1684</a>,8 +1684,7 @@ llvm::BasicBlock *CodeGenFunction::getEH<br>
   const char *RethrowName = Personality.CatchallRethrowFn;<br>
   if (RethrowName != nullptr && !isCleanup) {<br>
     EmitRuntimeCall(getCatchallRethrowFn(CGM, RethrowName),<br>
-                    getExceptionFromSlot())<br>
-      ->setDoesNotReturn();<br>
+                    getExceptionFromSlot())->setDoesNotReturn();<br>
     Builder.CreateUnreachable();<br>
     Builder.restoreIP(SavedIP);<br>
     return EHResumeBlock;<br>
@@ -1943,23 +1942,17 @@ void CodeGenFunction::ExitSEHTryStmt(con<br>
     Builder.SetInsertPoint(FI.FinallyBB);<br>
     EmitStmt(Finally->getBlock());<br>
<br>
-    // If the finally block doesn't fall through, we don't need these blocks.<br>
-    if (!HaveInsertPoint()) {<br>
-      FI.ContBB->eraseFromParent();<br>
-      if (FI.ResumeBB)<br>
-        FI.ResumeBB->eraseFromParent();<br>
-      return;<br>
-    }<br>
-<br>
-    if (FI.ResumeBB) {<br>
-      llvm::Value *IsEH = Builder.CreateLoad(getAbnormalTerminationSlot(),<br>
-                                             "abnormal.termination");<br>
-      IsEH = Builder.CreateICmpEQ(IsEH, llvm::ConstantInt::get(Int8Ty, 0));<br>
-      Builder.CreateCondBr(IsEH, FI.ContBB, FI.ResumeBB);<br>
-    } else {<br>
-      // There was nothing exceptional in the try body, so we only have normal<br>
-      // control flow.<br>
-      Builder.CreateBr(FI.ContBB);<br>
+    if (HaveInsertPoint()) {<br>
+      if (FI.ResumeBB) {<br>
+        llvm::Value *IsEH = Builder.CreateLoad(getAbnormalTerminationSlot(),<br>
+                                               "abnormal.termination");<br>
+        IsEH = Builder.CreateICmpEQ(IsEH, llvm::ConstantInt::get(Int8Ty, 0));<br>
+        Builder.CreateCondBr(IsEH, FI.ContBB, FI.ResumeBB);<br>
+      } else {<br>
+        // There was nothing exceptional in the try body, so we only have normal<br>
+        // control flow.<br>
+        Builder.CreateBr(FI.ContBB);<br>
+      }<br>
     }<br>
<br>
     Builder.restoreIP(SavedIP);<br>
<br>
Modified: cfe/trunk/test/CodeGen/exceptions-seh-finally.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-finally.c?rev=230697&r1=230696&r2=230697&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-finally.c?rev=230697&r1=230696&r2=230697&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/exceptions-seh-finally.c (original)<br>
+++ cfe/trunk/test/CodeGen/exceptions-seh-finally.c Thu Feb 26 16:34:33 2015<br>
@@ -193,12 +193,99 @@ int nested___finally___finally() {<br>
 // CHECK-NEXT: br label %[[finally:[^ ]*]]<br>
 //<br>
 // CHECK: [[finally]]<br>
-// CHECK-NEXT:  store i32 1, i32* %<br>
-// CHECK-NEXT:  store i8 0, i8* %<br>
+// CHECK-NEXT: store i32 1, i32* %<br>
+// CHECK-NEXT: store i32 1, i32* %<br>
+// CHECK-NEXT: br label %[[cleanup:[^ ]*]]<br>
+//<br>
+// The finally's unreachable continuation block:<br>
+// CHECK: store i32 0, i32* %<br>
+// CHECK-NEXT: br label %[[cleanup]]<br>
+//<br>
+// CHECK: [[cleanup]]<br>
+// CHECK-NEXT: store i8 0, i8* %<br>
 // CHECK-NEXT: br label %[[outerfinally:[^ ]*]]<br>
 //<br>
 // CHECK: [[outerfinally]]<br>
 // CHECK-NEXT: br label %[[finallycont:[^ ]*]]<br>
 //<br>
 // CHECK: [[finallycont]]<br>
-// CHECK-NEXT: ret i32 1<br>
+// CHECK-NEXT: %[[dest:[^ ]*]] = load i32* %<br>
+// CHECK-NEXT: switch i32 %[[dest]]<br>
+// CHECK-NEXT: i32 0, label %[[cleanupcont:[^ ]*]]<br>
+//<br>
+// CHECK: [[cleanupcont]]<br>
+// CHECK-NEXT: store i32 0, i32* %<br>
+// CHECK-NEXT: br label %[[return:[^ ]*]]<br>
+//<br>
+// CHECK: [[return]]<br>
+// CHECK-NEXT: %[[reg:[^ ]*]] = load i32* %<br>
+// CHECK-NEXT: ret i32 %[[reg]]<br>
+<br>
+int nested___finally___finally_with_eh_edge() {<br>
+  __try {<br>
+    __try {<br>
+      might_crash();<br>
+    } __finally {<br>
+      return 899;<br>
+    }<br>
+  } __finally {<br>
+    // Intentionally no return here.<br>
+  }<br>
+  return 912;<br>
+}<br>
+// CHECK-LABEL: define i32 @nested___finally___finally_with_eh_edge<br>
+// CHECK: invoke void @might_crash() #3<br>
+// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad:[^ ]*]]<br>
+//<br>
+// CHECK: [[invokecont]]<br>
+// CHECK-NEXT: store i8 0, i8* %[[abnormal:[^ ]*]]<br>
+// CHECK-NEXT: br label %[[finally:[^ ]*]]<br>
+<br>
+// CHECK: [[finally]]<br>
+// CHECK-NEXT: store i32 899, i32* %<br>
+// CHECK-NEXT: store i32 1, i32* %<br>
+// CHECK-NEXT: br label %[[cleanup:[^ ]*]]<br>
+//<br>
+// The inner finally's unreachable continuation block:<br>
+// CHECK: store i32 0, i32* %<br>
+// CHECK-NEXT: br label %[[cleanup]]<br>
+//<br>
+// CHECK: [[cleanup]]<br>
+// CHECK-NEXT: store i8 0, i8* %<br>
+// CHECK-NEXT: br label %[[outerfinally:[^ ]*]]<br>
+//<br>
+// CHECK: [[outerfinally]]<br>
+// CHECK-NEXT: %[[abnormallocal:[^ ]*]] = load i8* %[[abnormal]]<br>
+// CHECK-NEXT: %[[reg:[^ ]*]] = icmp eq i8 %[[abnormallocal]], 0<br>
+// CHECK-NEXT: br i1 %[[reg]], label %[[finallycont:[^ ]*]], label %[[finallyresume:[^ ]*]]<br>
+//<br>
+// CHECK: [[finallycont]]<br>
+// CHECK-NEXT: %[[dest:[^ ]*]] = load i32* %<br>
+// CHECK-NEXT: switch i32 %[[dest]]<br>
+// CHECK-NEXT: i32 0, label %[[cleanupcont:[^ ]*]]<br>
+//<br>
+// CHECK: [[cleanupcont]]<br>
+// CHECK-NEXT: store i32 912, i32* %<br>
+// CHECK-NEXT: br label %[[return:[^ ]*]]<br>
+//<br>
+//<br>
+// CHECK: [[lpad]]<br>
+// CHECK-NEXT: landingpad<br>
+// CHECK-NEXT: cleanup<br>
+// CHECK: store i8 1, i8* %[[abnormal]]<br>
+// CHECK: br label %[[finally]]<br>
+//<br>
+// The inner finally's unreachable resume block:<br>
+// CHECK: store i8 1, i8* %[[abnormal]]<br>
+// CHECK-NEXT: br label %[[outerfinally]]<br>
+//<br>
+// CHECK: [[finallyresume]]<br>
+// CHECK-NEXT: br label %[[ehresume:[^ ]*]]<br>
+//<br>
+// CHECK: [[return]]<br>
+// CHECK-NEXT: %[[reg:[^ ]*]] = load i32* %<br>
+// CHECK-NEXT: ret i32 %[[reg]]<br>
+//<br>
+// The ehresume block, not reachable either.<br>
+// CHECK: [[ehresume]]<br>
+// CHECK: resume<br>
<br>
Modified: cfe/trunk/test/CodeGen/exceptions-seh-leave.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-leave.c?rev=230697&r1=230696&r2=230697&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-leave.c?rev=230697&r1=230696&r2=230697&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/exceptions-seh-leave.c (original)<br>
+++ cfe/trunk/test/CodeGen/exceptions-seh-leave.c Thu Feb 26 16:34:33 2015<br>
@@ -162,6 +162,13 @@ int nested___except___finally() {<br>
 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]<br>
 // CHECK-NOT: store i32 23<br>
<br>
+// Unused __finally continuation block<br>
+// CHECK: store i32 51, i32* %<br>
+// CHECK-NEXT: br label %[[tryleave]]<br>
+<br>
+// CHECK: [[tryleave]]<br>
+// CHECK-NEXT: br label %[[trycont:[^ ]*]]<br>
+<br>
 // CHECK: [[g1_lpad]]<br>
 // CHECK: store i8 1, i8* %<br>
 // CHECK-NEXT:  br label %[[finally]]<br>
@@ -171,14 +178,11 @@ int nested___except___finally() {<br>
 // CHECK: br label %[[except:[^ ]*]]<br>
<br>
 // CHECK: [[except]]<br>
-// CHECK-NEXT: br label %[[trycont:[^ ]*]]<br>
+// CHECK-NEXT: br label %[[trycont]]<br>
<br>
 // CHECK: [[trycont]]<br>
 // CHECK-NEXT: ret i32 1<br>
<br>
-// CHECK: [[tryleave]]<br>
-// CHECK-NEXT: br label %[[trycont]]<br>
-<br>
 int nested___except___except() {<br>
   int myres = 0;<br>
   __try {<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>