Model temporary destructors from logical operators with known values.
If the truth value of a LHS is known, we can build the knowledge whether a temporary destructor is executed or not into the CFG. This is needed by the return type analysis. llvm-svn: 215118
This commit is contained in:
parent
a3ddbc9d23
commit
7c03013c8b
|
@ -3631,12 +3631,23 @@ CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors(
|
|||
BinaryOperator *E, TempDtorContext &Context) {
|
||||
if (E->isLogicalOp()) {
|
||||
VisitForTemporaryDtors(E->getLHS(), false, Context);
|
||||
// We do not know at CFG-construction time whether the right-hand-side was
|
||||
// executed, thus we add a branch node that depends on the temporary
|
||||
// constructor call.
|
||||
TryResult LHSVal = tryEvaluateBool(E->getLHS());
|
||||
bool RHSNotExecuted = (E->getOpcode() == BO_LAnd && LHSVal.isFalse()) ||
|
||||
(E->getOpcode() == BO_LOr && LHSVal.isTrue());
|
||||
if (RHSNotExecuted) {
|
||||
return Block;
|
||||
}
|
||||
|
||||
TempDtorContext RHSContext(/*IsConditional=*/true);
|
||||
VisitForTemporaryDtors(E->getRHS(), false, RHSContext);
|
||||
InsertTempDtorDecisionBlock(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())
|
||||
InsertTempDtorDecisionBlock(RHSContext);
|
||||
|
||||
return Block;
|
||||
}
|
||||
|
||||
|
|
|
@ -183,6 +183,22 @@ int testTernaryConditionalNoreturnFalseBranch(bool value) {
|
|||
value ? Return() : (NoReturn() || NoReturn());
|
||||
} // expected-warning {{control may reach end of non-void function}}
|
||||
|
||||
int testStaticallyExecutedLogicalOrBranch() {
|
||||
false || NoReturn();
|
||||
}
|
||||
|
||||
int testStaticallyExecutedLogicalAndBranch() {
|
||||
true && NoReturn();
|
||||
}
|
||||
|
||||
int testStaticallySkippedLogicalOrBranch() {
|
||||
true || NoReturn();
|
||||
} // expected-warning {{control reaches end of non-void function}}
|
||||
|
||||
int testStaticallySkppedLogicalAndBranch() {
|
||||
false && NoReturn();
|
||||
} // expected-warning {{control reaches end of non-void function}}
|
||||
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
namespace LambdaVsTemporaryDtor {
|
||||
|
|
Loading…
Reference in New Issue