mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-02 21:22:44 +00:00
Don't crash when emitting a glvalue conditional where one arm is a
throw-expression. Based on a patch by Marius Wachtler! llvm-svn: 211388
This commit is contained in:
parent
5c4a3d3118
commit
f3076ff2fd
@ -2684,6 +2684,19 @@ LValue CodeGenFunction::EmitInitListLValue(const InitListExpr *E) {
|
||||
return EmitLValue(E->getInit(0));
|
||||
}
|
||||
|
||||
/// Emit the operand of a glvalue conditional operator. This is either a glvalue
|
||||
/// or a (possibly-parenthesized) throw-expression. If this is a throw, no
|
||||
/// LValue is returned and the current block has been terminated.
|
||||
static Optional<LValue> EmitLValueOrThrowExpression(CodeGenFunction &CGF,
|
||||
const Expr *Operand) {
|
||||
if (auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
|
||||
CGF.EmitCXXThrowExpr(ThrowExpr, /*KeepInsertionPoint*/false);
|
||||
return None;
|
||||
}
|
||||
|
||||
return CGF.EmitLValue(Operand);
|
||||
}
|
||||
|
||||
LValue CodeGenFunction::
|
||||
EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
|
||||
if (!expr->isGLValue()) {
|
||||
@ -2721,31 +2734,40 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
|
||||
EmitBlock(lhsBlock);
|
||||
Cnt.beginRegion(Builder);
|
||||
eval.begin(*this);
|
||||
LValue lhs = EmitLValue(expr->getTrueExpr());
|
||||
Optional<LValue> lhs =
|
||||
EmitLValueOrThrowExpression(*this, expr->getTrueExpr());
|
||||
eval.end(*this);
|
||||
|
||||
if (!lhs.isSimple())
|
||||
if (lhs && !lhs->isSimple())
|
||||
return EmitUnsupportedLValue(expr, "conditional operator");
|
||||
|
||||
lhsBlock = Builder.GetInsertBlock();
|
||||
Builder.CreateBr(contBlock);
|
||||
if (lhs)
|
||||
Builder.CreateBr(contBlock);
|
||||
|
||||
// Any temporaries created here are conditional.
|
||||
EmitBlock(rhsBlock);
|
||||
eval.begin(*this);
|
||||
LValue rhs = EmitLValue(expr->getFalseExpr());
|
||||
Optional<LValue> rhs =
|
||||
EmitLValueOrThrowExpression(*this, expr->getFalseExpr());
|
||||
eval.end(*this);
|
||||
if (!rhs.isSimple())
|
||||
if (rhs && !rhs->isSimple())
|
||||
return EmitUnsupportedLValue(expr, "conditional operator");
|
||||
rhsBlock = Builder.GetInsertBlock();
|
||||
|
||||
EmitBlock(contBlock);
|
||||
|
||||
llvm::PHINode *phi = Builder.CreatePHI(lhs.getAddress()->getType(), 2,
|
||||
"cond-lvalue");
|
||||
phi->addIncoming(lhs.getAddress(), lhsBlock);
|
||||
phi->addIncoming(rhs.getAddress(), rhsBlock);
|
||||
return MakeAddrLValue(phi, expr->getType());
|
||||
if (lhs && rhs) {
|
||||
llvm::PHINode *phi = Builder.CreatePHI(lhs->getAddress()->getType(),
|
||||
2, "cond-lvalue");
|
||||
phi->addIncoming(lhs->getAddress(), lhsBlock);
|
||||
phi->addIncoming(rhs->getAddress(), rhsBlock);
|
||||
return MakeAddrLValue(phi, expr->getType());
|
||||
} else {
|
||||
assert((lhs || rhs) &&
|
||||
"both operands of glvalue conditional are throw-expressions?");
|
||||
return lhs ? *lhs : *rhs;
|
||||
}
|
||||
}
|
||||
|
||||
/// EmitCastLValue - Casts are never lvalues unless that cast is to a reference
|
||||
|
@ -80,3 +80,35 @@ namespace DR1560 {
|
||||
// CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE
|
||||
// CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define void @_Z5test7b(
|
||||
void test7(bool cond) {
|
||||
// CHECK: br i1
|
||||
//
|
||||
// x.true:
|
||||
// CHECK: call void @__cxa_throw(
|
||||
// CHECK-NEXT: unreachable
|
||||
//
|
||||
// x.false:
|
||||
// CHECK: br label
|
||||
//
|
||||
// end:
|
||||
// CHECK: ret void
|
||||
cond ? throw test7 : val;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define nonnull i32* @_Z5test8b(
|
||||
int &test8(bool cond) {
|
||||
// CHECK: br i1
|
||||
//
|
||||
// x.true:
|
||||
// CHECK: br label
|
||||
//
|
||||
// x.false:
|
||||
// CHECK: call void @__cxa_throw(
|
||||
// CHECK-NEXT: unreachable
|
||||
//
|
||||
// end:
|
||||
// CHECK: ret i32* @val
|
||||
return cond ? val : ((throw "foo"));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user