Only have one path in the CFG for ternaries if the condition is known.

The return type analysis requires that the CFG is simplified when the
truth values of branches are statically known at analysis time.

llvm-svn: 215114
This commit is contained in:
Manuel Klimek 2014-08-07 14:25:43 +00:00
parent b0ece4e07d
commit 0ce9108104
2 changed files with 27 additions and 2 deletions

View File

@ -3711,15 +3711,24 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors(
VisitForTemporaryDtors(E->getCond(), false, Context);
CFGBlock *ConditionBlock = Block;
CFGBlock *ConditionSucc = Succ;
TryResult ConditionVal = tryEvaluateBool(E->getCond());
TempDtorContext TrueContext(/*IsConditional=*/true);
VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext);
if (!ConditionVal.isFalse()) {
VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext);
if (ConditionVal.isTrue())
return Block;
}
CFGBlock *TrueBlock = Block;
Block = ConditionBlock;
Succ = ConditionSucc;
TempDtorContext FalseContext(/*IsConditional=*/true);
VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext);
if (!ConditionVal.isTrue()) {
VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext);
if (ConditionVal.isFalse())
return Block;
}
if (TrueContext.TerminatorExpr && FalseContext.TerminatorExpr) {
InsertTempDtorDecisionBlock(FalseContext, TrueBlock);

View File

@ -159,6 +159,22 @@ int testTernaryUnconditionalNoreturn() {
true ? NoReturn() : NoReturn();
}
int testTernaryStaticallyConditionalNoretrunOnTrue() {
true ? NoReturn() : Return();
}
int testTernaryStaticallyConditionalRetrunOnTrue() {
true ? Return() : NoReturn();
} // expected-warning {{control reaches end of non-void function}}
int testTernaryStaticallyConditionalNoretrunOnFalse() {
false ? Return() : NoReturn();
}
int testTernaryStaticallyConditionalRetrunOnFalse() {
false ? NoReturn() : Return();
} // expected-warning {{control reaches end of non-void function}}
int testTernaryConditionalNoreturnTrueBranch(bool value) {
value ? (NoReturn() || NoReturn()) : Return();
} // expected-warning {{control may reach end of non-void function}}