Fix CFG for temporary dtors when the branch taken is known.

Use the parent context when visiting temporaries when we do not insert a
temporary dtor decision branch.

llvm-svn: 215120
This commit is contained in:
Manuel Klimek 2014-08-07 17:02:21 +00:00
parent c349434010
commit cadc603e91
2 changed files with 29 additions and 14 deletions

View File

@ -3638,15 +3638,17 @@ CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors(
return Block;
}
TempDtorContext RHSContext(/*IsConditional=*/true);
VisitForTemporaryDtors(E->getRHS(), false, RHSContext);
// If the LHS is known, and the RHS is not executed, we returned above.
// Thus, once we arrive here, and the LHS is known, we also know that the
// RHS was executed and can execute the RHS unconditionally (that is, we
// don't insert a decision block).
if (!LHSVal.isKnown())
if (LHSVal.isKnown()) {
VisitForTemporaryDtors(E->getRHS(), false, Context);
} else {
TempDtorContext RHSContext(/*IsConditional=*/true);
VisitForTemporaryDtors(E->getRHS(), false, RHSContext);
InsertTempDtorDecisionBlock(RHSContext);
}
return Block;
}
@ -3724,22 +3726,24 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors(
CFGBlock *ConditionSucc = Succ;
TryResult ConditionVal = tryEvaluateBool(E->getCond());
TempDtorContext TrueContext(/*IsConditional=*/true);
if (!ConditionVal.isFalse()) {
VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext);
if (ConditionVal.isTrue())
return Block;
if (ConditionVal.isKnown()) {
if (ConditionVal.isTrue()) {
VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, Context);
} else {
assert(ConditionVal.isFalse());
VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, Context);
}
return Block;
}
TempDtorContext TrueContext(/*IsConditional=*/true);
VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext);
CFGBlock *TrueBlock = Block;
Block = ConditionBlock;
Succ = ConditionSucc;
TempDtorContext FalseContext(/*IsConditional=*/true);
if (!ConditionVal.isTrue()) {
VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext);
if (ConditionVal.isFalse())
return Block;
}
VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext);
if (TrueContext.TerminatorExpr && FalseContext.TerminatorExpr) {
InsertTempDtorDecisionBlock(FalseContext, TrueBlock);

View File

@ -183,6 +183,14 @@ int testTernaryConditionalNoreturnFalseBranch(bool value) {
value ? Return() : (NoReturn() || NoReturn());
} // expected-warning {{control may reach end of non-void function}}
int testConditionallyExecutedComplexTernaryTrueBranch(bool value) {
value || (true ? NoReturn() : true);
} // expected-warning {{control may reach end of non-void function}}
int testConditionallyExecutedComplexTernaryFalseBranch(bool value) {
value || (false ? true : NoReturn());
} // expected-warning {{control may reach end of non-void function}}
int testStaticallyExecutedLogicalOrBranch() {
false || NoReturn();
}
@ -199,6 +207,9 @@ int testStaticallySkppedLogicalAndBranch() {
false && NoReturn();
} // expected-warning {{control reaches end of non-void function}}
int testConditionallyExecutedComplexLogicalBranch(bool value) {
value || (true && NoReturn());
} // expected-warning {{control may reach end of non-void function}}
#if __cplusplus >= 201103L
namespace LambdaVsTemporaryDtor {