aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-05-08 09:20:56 +0000
committerBill Wendling <isanbard@gmail.com>2013-05-08 09:20:56 +0000
commit6acf861cfca57327d2bb91027f75e3e6f73249b5 (patch)
tree0890d2178878359a2c5fd6aab07dcc5506f1bc2f /lib/CodeGen
parent4066c53654fa11fc2e72e4b3b7f4be9153fadc08 (diff)
Merging r181368:
------------------------------------------------------------------------ r181368 | rsmith | 2013-05-07 14:53:22 -0700 (Tue, 07 May 2013) | 3 lines Don't crash in IRGen if a conditional with 'throw' in one of its branches is used as a branch condition. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_33@181401 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGException.cpp12
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp10
-rw-r--r--lib/CodeGen/CodeGenFunction.h2
3 files changed, 19 insertions, 5 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 36642bcc48..a088d78641 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -419,14 +419,16 @@ llvm::Value *CodeGenFunction::getSelectorFromSlot() {
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(const CXXThrowExpr *E) {
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(const CXXThrowExpr *E) {
// 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) {
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 791c1a8152..75c60edbba 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -928,6 +928,16 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
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);
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 08e60c43ce..ff74c15c38 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -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);