Skip to content

Commit 2429009

Browse files
author
Your Name
committed
Refactor into reusable function
1 parent 039a7c0 commit 2429009

1 file changed

Lines changed: 34 additions & 27 deletions

File tree

lib/forwardanalyzer.cpp

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,28 @@ namespace {
407407
return p;
408408
}
409409

410+
// Update the branch that the evaluated condition takes
411+
Progress updateTakenBranch(Branch& branch, const Token* skippedBlock, const Token* condTok, int depth)
412+
{
413+
// The condition is only "known" because of an earlier assumption, so the
414+
// skipped block could still modify the value -> lower to possible
415+
if (!condTok->hasKnownIntValue() && skippedBlock && analyzeScope(skippedBlock).isModified() &&
416+
!analyzer->lowerToPossible())
417+
return Break(Analyzer::Terminate::Bail);
418+
if (!branch.endBlock)
419+
return Progress::Continue;
420+
updateScopeState(branch.endBlock);
421+
if (updateBranch(branch, depth - 1) == Progress::Break)
422+
return Progress::Break;
423+
// The branch was entered because of the tracked value; if it might not
424+
// return (it ends in a call to an unknown, possibly noreturn function)
425+
// then the value might not flow past the branch.
426+
if (!condTok->hasKnownIntValue() && !branch.escape && branch.escapeUnknown &&
427+
!analyzer->lowerToInconclusive())
428+
return Break(Analyzer::Terminate::Bail);
429+
return Progress::Continue;
430+
}
431+
410432
bool reentersLoop(Token* endBlock, const Token* condTok, const Token* stepTok) const {
411433
if (!condTok)
412434
return true;
@@ -558,16 +580,21 @@ namespace {
558580
return updateLoop(endToken, endBlock, condTok, initTok, stepTok, true);
559581
}
560582

561-
Progress updateScope(Token* endBlock, int depth = 20)
583+
void updateScopeState(const Token* endBlock)
562584
{
563-
if (!endBlock)
564-
return Break();
565585
assert(endBlock->link());
566-
Token* ctx = endBlock->link()->previous();
586+
const Token* ctx = endBlock->link()->previous();
567587
if (Token::simpleMatch(ctx, ")"))
568588
ctx = ctx->link()->previous();
569589
if (ctx)
570590
analyzer->updateState(ctx);
591+
}
592+
593+
Progress updateScope(Token* endBlock, int depth = 20)
594+
{
595+
if (!endBlock)
596+
return Break();
597+
updateScopeState(endBlock);
571598
return updateRange(endBlock->link(), endBlock, depth);
572599
}
573600

@@ -738,32 +765,12 @@ namespace {
738765
const bool hasElse = Token::simpleMatch(endBlock, "} else {");
739766
tok = hasElse ? endBlock->linkAt(2) : endBlock;
740767
if (thenBranch.check) {
741-
// The condition is only "known" because of an earlier assumption, so the
742-
// skipped else block could still modify the value -> lower to possible
743-
if (!condTok->hasKnownIntValue() && hasElse &&
744-
analyzeScope(elseBranch.endBlock).isModified() && !analyzer->lowerToPossible())
745-
return Break(Analyzer::Terminate::Bail);
746-
if (updateScope(thenBranch.endBlock, depth - 1) == Progress::Break)
768+
if (updateTakenBranch(thenBranch, hasElse ? elseBranch.endBlock : nullptr, condTok, depth) ==
769+
Progress::Break)
747770
return Break();
748-
// The branch was entered because of the tracked value; if it might not
749-
// return (it ends in a call to an unknown, possibly noreturn function)
750-
// then the value might not flow past the branch.
751-
if (!condTok->hasKnownIntValue() &&
752-
!isEscapeScope(thenBranch.endBlock, thenBranch.escapeUnknown) &&
753-
thenBranch.escapeUnknown && !analyzer->lowerToInconclusive())
754-
return Break(Analyzer::Terminate::Bail);
755771
} else if (elseBranch.check) {
756-
// Likewise the skipped then block could still modify the value
757-
if (!condTok->hasKnownIntValue() && analyzeScope(thenBranch.endBlock).isModified() &&
758-
!analyzer->lowerToPossible())
759-
return Break(Analyzer::Terminate::Bail);
760-
if (elseBranch.endBlock && updateScope(elseBranch.endBlock, depth - 1) == Progress::Break)
772+
if (updateTakenBranch(elseBranch, thenBranch.endBlock, condTok, depth) == Progress::Break)
761773
return Break();
762-
// Same as above: an else branch that might not return
763-
if (elseBranch.endBlock && !condTok->hasKnownIntValue() &&
764-
!isEscapeScope(elseBranch.endBlock, elseBranch.escapeUnknown) &&
765-
elseBranch.escapeUnknown && !analyzer->lowerToInconclusive())
766-
return Break(Analyzer::Terminate::Bail);
767774
} else {
768775
const bool conditional = stopOnCondition(condTok);
769776
// The value only flows into the then-branch when the condition can split

0 commit comments

Comments
 (0)