r181368 - Don't crash in IRGen if a conditional with 'throw' in one of its branches is

Richard Smith richard-llvm at metafoo.co.uk
Tue May 7 14:53:22 PDT 2013


Author: rsmith
Date: Tue May  7 16:53:22 2013
New Revision: 181368

URL: http://llvm.org/viewvc/llvm-project?rev=181368&view=rev
Log:
Don't crash in IRGen if a conditional with 'throw' in one of its branches is
used as a branch condition.

Modified:
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGenCXX/throw-expressions.cpp

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=181368&r1=181367&r2=181368&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Tue May  7 16:53:22 2013
@@ -419,14 +419,16 @@ llvm::Value *CodeGenFunction::getSelecto
   return Builder.CreateLoad(getEHSelectorSlot(), "sel");
 }
 
-void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
+void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
+                                       bool KeepInsertionPoint) {
   if (!E->getSubExpr()) {
     EmitNoreturnRuntimeCallOrInvoke(getReThrowFn(CGM),
                                     ArrayRef<llvm::Value*>());
 
     // throw is an expression, and the expression emitters expect us
     // to leave ourselves at a valid insertion point.
-    EmitBlock(createBasicBlock("throw.cont"));
+    if (KeepInsertionPoint)
+      EmitBlock(createBasicBlock("throw.cont"));
 
     return;
   }
@@ -440,7 +442,8 @@ void CodeGenFunction::EmitCXXThrowExpr(c
     CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);
     // This will clear insertion point which was not cleared in
     // call to EmitThrowStmt.
-    EmitBlock(createBasicBlock("throw.cont"));
+    if (KeepInsertionPoint)
+      EmitBlock(createBasicBlock("throw.cont"));
     return;
   }
   
@@ -478,7 +481,8 @@ void CodeGenFunction::EmitCXXThrowExpr(c
 
   // throw is an expression, and the expression emitters expect us
   // to leave ourselves at a valid insertion point.
-  EmitBlock(createBasicBlock("throw.cont"));
+  if (KeepInsertionPoint)
+    EmitBlock(createBasicBlock("throw.cont"));
 }
 
 void CodeGenFunction::EmitStartEHSpec(const Decl *D) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=181368&r1=181367&r2=181368&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue May  7 16:53:22 2013
@@ -928,6 +928,16 @@ void CodeGenFunction::EmitBranchOnBoolEx
     return;
   }
 
+  if (const CXXThrowExpr *Throw = dyn_cast<CXXThrowExpr>(Cond)) {
+    // Conditional operator handling can give us a throw expression as a
+    // condition for a case like:
+    //   br(c ? throw x : y, t, f) -> br(c, br(throw x, t, f), br(y, t, f)
+    // Fold this to:
+    //   br(c, throw x, br(y, t, f))
+    EmitCXXThrowExpr(Throw, /*KeepInsertionPoint*/false);
+    return;
+  }
+
   // Emit the code with the fully general case.
   llvm::Value *CondV = EvaluateExprAsBool(Cond);
   Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=181368&r1=181367&r2=181368&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue May  7 16:53:22 2013
@@ -2708,7 +2708,7 @@ public:
   }
   void enterNonTrivialFullExpression(const ExprWithCleanups *E);
 
-  void EmitCXXThrowExpr(const CXXThrowExpr *E);
+  void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint = true);
 
   void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest);
 

Modified: cfe/trunk/test/CodeGenCXX/throw-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/throw-expressions.cpp?rev=181368&r1=181367&r2=181368&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/throw-expressions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/throw-expressions.cpp Tue May  7 16:53:22 2013
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm-only -verify %s -Wno-unreachable-code
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -Wno-unreachable-code -Werror -emit-llvm -o - %s | FileCheck %s
 // expected-no-diagnostics
 
 int val = 42;
@@ -19,3 +19,28 @@ void test3() {
 int test4() {
   return 1 ? throw val : val;
 }
+
+// PR15923
+int test5(bool x, bool y, int z) {
+  return (x ? throw 1 : y) ? z : throw 2;
+}
+// CHECK: define i32 @_Z5test5bbi(
+// CHECK: br i1
+//
+// x.true:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// x.false:
+// CHECK: br i1
+//
+// y.true:
+// CHECK: load i32*
+// CHECK: br label
+//
+// y.false:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// end:
+// CHECK: ret i32





More information about the cfe-commits mailing list