forked from OSchip/llvm-project
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:
parent
c349434010
commit
cadc603e91
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue