Mark successors as reachable/unreachable instead of changing the CFG.

As suggested by Ted, this makes a few warnings less aggressive.

llvm-svn: 215128
This commit is contained in:
Manuel Klimek 2014-08-07 18:44:19 +00:00
parent 1b9f936f91
commit edf925b935
2 changed files with 22 additions and 35 deletions

View File

@ -479,6 +479,7 @@ private:
AbstractConditionalOperator *E, bool BindToTemporary, AbstractConditionalOperator *E, bool BindToTemporary,
TempDtorContext &Context); TempDtorContext &Context);
void InsertTempDtorDecisionBlock(const TempDtorContext &Context, void InsertTempDtorDecisionBlock(const TempDtorContext &Context,
TryResult ConditionVal,
CFGBlock *FalseSucc = nullptr); CFGBlock *FalseSucc = nullptr);
// NYS == Not Yet Supported // NYS == Not Yet Supported
@ -3631,24 +3632,16 @@ CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors(
BinaryOperator *E, TempDtorContext &Context) { BinaryOperator *E, TempDtorContext &Context) {
if (E->isLogicalOp()) { if (E->isLogicalOp()) {
VisitForTemporaryDtors(E->getLHS(), false, Context); VisitForTemporaryDtors(E->getLHS(), false, Context);
TryResult LHSVal = tryEvaluateBool(E->getLHS()); TryResult RHSExecuted = tryEvaluateBool(E->getLHS());
bool RHSNotExecuted = (E->getOpcode() == BO_LAnd && LHSVal.isFalse()) || if (RHSExecuted.isKnown() && E->getOpcode() == BO_LOr)
(E->getOpcode() == BO_LOr && LHSVal.isTrue()); RHSExecuted.negate();
if (RHSNotExecuted) {
return Block;
}
// If the LHS is known, and the RHS is not executed, we returned above. // We do not know at CFG-construction time whether the right-hand-side was
// Thus, once we arrive here, and the LHS is known, we also know that the // executed, thus we add a branch node that depends on the temporary
// RHS was executed and can execute the RHS unconditionally (that is, we // constructor call.
// don't insert a decision block). TempDtorContext RHSContext(/*IsConditional=*/true);
if (LHSVal.isKnown()) { VisitForTemporaryDtors(E->getRHS(), false, RHSContext);
VisitForTemporaryDtors(E->getRHS(), false, Context); InsertTempDtorDecisionBlock(RHSContext, RHSExecuted);
} else {
TempDtorContext RHSContext(/*IsConditional=*/true);
VisitForTemporaryDtors(E->getRHS(), false, RHSContext);
InsertTempDtorDecisionBlock(RHSContext);
}
return Block; return Block;
} }
@ -3705,6 +3698,7 @@ CFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors(
} }
void CFGBuilder::InsertTempDtorDecisionBlock(const TempDtorContext &Context, void CFGBuilder::InsertTempDtorDecisionBlock(const TempDtorContext &Context,
TryResult ConditionVal,
CFGBlock *FalseSucc) { CFGBlock *FalseSucc) {
if (!Context.TerminatorExpr) { if (!Context.TerminatorExpr) {
// If no temporary was found, we do not need to insert a decision point. // If no temporary was found, we do not need to insert a decision point.
@ -3713,8 +3707,9 @@ void CFGBuilder::InsertTempDtorDecisionBlock(const TempDtorContext &Context,
assert(Context.TerminatorExpr); assert(Context.TerminatorExpr);
CFGBlock *Decision = createBlock(false); CFGBlock *Decision = createBlock(false);
Decision->setTerminator(CFGTerminator(Context.TerminatorExpr, true)); Decision->setTerminator(CFGTerminator(Context.TerminatorExpr, true));
addSuccessor(Decision, Block); addSuccessor(Decision, Block, !ConditionVal.isFalse());
addSuccessor(Decision, FalseSucc ? FalseSucc : Context.Succ); addSuccessor(Decision, FalseSucc ? FalseSucc : Context.Succ,
!ConditionVal.isTrue());
Block = Decision; Block = Decision;
} }
@ -3725,16 +3720,8 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors(
CFGBlock *ConditionBlock = Block; CFGBlock *ConditionBlock = Block;
CFGBlock *ConditionSucc = Succ; CFGBlock *ConditionSucc = Succ;
TryResult ConditionVal = tryEvaluateBool(E->getCond()); TryResult ConditionVal = tryEvaluateBool(E->getCond());
TryResult NegatedVal = ConditionVal;
if (ConditionVal.isKnown()) { if (NegatedVal.isKnown()) NegatedVal.negate();
if (ConditionVal.isTrue()) {
VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, Context);
} else {
assert(ConditionVal.isFalse());
VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, Context);
}
return Block;
}
TempDtorContext TrueContext(/*IsConditional=*/true); TempDtorContext TrueContext(/*IsConditional=*/true);
VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext); VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext);
@ -3746,12 +3733,12 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors(
VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext); VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext);
if (TrueContext.TerminatorExpr && FalseContext.TerminatorExpr) { if (TrueContext.TerminatorExpr && FalseContext.TerminatorExpr) {
InsertTempDtorDecisionBlock(FalseContext, TrueBlock); InsertTempDtorDecisionBlock(FalseContext, NegatedVal, TrueBlock);
} else if (TrueContext.TerminatorExpr) { } else if (TrueContext.TerminatorExpr) {
Block = TrueBlock; Block = TrueBlock;
InsertTempDtorDecisionBlock(TrueContext); InsertTempDtorDecisionBlock(TrueContext, ConditionVal);
} else { } else {
InsertTempDtorDecisionBlock(FalseContext); InsertTempDtorDecisionBlock(FalseContext, NegatedVal);
} }
return Block; return Block;
} }

View File

@ -185,11 +185,11 @@ int testTernaryConditionalNoreturnFalseBranch(bool value) {
int testConditionallyExecutedComplexTernaryTrueBranch(bool value) { int testConditionallyExecutedComplexTernaryTrueBranch(bool value) {
value || (true ? NoReturn() : true); value || (true ? NoReturn() : true);
} // expected-warning {{control may reach end of non-void function}} }
int testConditionallyExecutedComplexTernaryFalseBranch(bool value) { int testConditionallyExecutedComplexTernaryFalseBranch(bool value) {
value || (false ? true : NoReturn()); value || (false ? true : NoReturn());
} // expected-warning {{control may reach end of non-void function}} }
int testStaticallyExecutedLogicalOrBranch() { int testStaticallyExecutedLogicalOrBranch() {
false || NoReturn(); false || NoReturn();
@ -209,7 +209,7 @@ int testStaticallySkppedLogicalAndBranch() {
int testConditionallyExecutedComplexLogicalBranch(bool value) { int testConditionallyExecutedComplexLogicalBranch(bool value) {
value || (true && NoReturn()); value || (true && NoReturn());
} // expected-warning {{control may reach end of non-void function}} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
namespace LambdaVsTemporaryDtor { namespace LambdaVsTemporaryDtor {