Skip to content

Commit bf40b4a

Browse files
committed
Fix #12861 Hang in valueFlowCondition() with huge array
1 parent 3529cd6 commit bf40b4a

19 files changed

+64
-45
lines changed

lib/astutils.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,9 @@ static const Token * getVariableInitExpression(const Variable * var)
10131013

10141014
const Token* isInLoopCondition(const Token* tok)
10151015
{
1016-
const Token* top = tok->astTop();
1016+
if (!tok)
1017+
return nullptr;
1018+
const Token* top = tok->astTop(true);
10171019
return Token::Match(top->previous(), "for|while (") ? top : nullptr;
10181020
}
10191021

@@ -2243,12 +2245,12 @@ bool isReturnScope(const Token* const endToken, const Library& library, const To
22432245
!Token::findsimplematch(prev->link(), "break", prev)) {
22442246
return isReturnScope(prev, library, unknownFunc, functionScope);
22452247
}
2246-
if (isEscaped(prev->link()->astTop(), functionScope, library))
2248+
if (isEscaped(prev->link()->astTop(true), functionScope, library))
22472249
return true;
22482250
if (Token::Match(prev->link()->previous(), "[;{}] {"))
22492251
return isReturnScope(prev, library, unknownFunc, functionScope);
22502252
} else if (Token::simpleMatch(prev, ";")) {
2251-
if (prev->tokAt(-2) && hasNoreturnFunction(prev->tokAt(-2)->astTop(), library, unknownFunc))
2253+
if (prev->tokAt(-2) && hasNoreturnFunction(prev->tokAt(-2)->astTop(true), library, unknownFunc))
22522254
return true;
22532255
// Unknown symbol
22542256
if (Token::Match(prev->tokAt(-2), ";|}|{ %name% ;") && prev->previous()->isIncompleteVar()) {
@@ -2257,9 +2259,9 @@ bool isReturnScope(const Token* const endToken, const Library& library, const To
22572259
return false;
22582260
}
22592261
if (Token::simpleMatch(prev->previous(), ") ;") && prev->linkAt(-1) &&
2260-
isEscaped(prev->linkAt(-1)->astTop(), functionScope, library))
2262+
isEscaped(prev->linkAt(-1)->astTop(true), functionScope, library))
22612263
return true;
2262-
if (isEscaped(prev->previous()->astTop(), functionScope, library))
2264+
if (isEscaped(prev->previous()->astTop(true), functionScope, library))
22632265
return true;
22642266
// return/goto statement
22652267
prev = prev->previous();

lib/checkautovariables.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ static bool isDeadTemporary(const Token* tok, const Token* expr, const Library&
468468
if (!isTemporary(tok, &library))
469469
return false;
470470
if (expr) {
471-
if (!precedes(nextAfterAstRightmostLeaf(tok->astTop()), nextAfterAstRightmostLeaf(expr->astTop())))
471+
if (!precedes(nextAfterAstRightmostLeaf(tok->astTop(true)), nextAfterAstRightmostLeaf(expr->astTop(true))))
472472
return false;
473473
const Token* parent = tok->astParent();
474474
if (Token::simpleMatch(parent, "{") && Token::simpleMatch(parent->astParent(), ":"))
@@ -642,7 +642,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
642642
}
643643
if (!ValueFlow::isLifetimeBorrowed(tok, *mSettings))
644644
continue;
645-
const Token* nextTok = nextAfterAstRightmostLeaf(tok->astTop());
645+
const Token* nextTok = nextAfterAstRightmostLeaf(tok->astTop(true));
646646
if (!nextTok)
647647
nextTok = tok->next();
648648
if (var && (!var->isLocal() || var->isStatic()) && !var->isArgument() && !(val.tokvalue && val.tokvalue->variable() && val.tokvalue->variable()->isStatic()) &&

lib/checkclass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,7 +1877,7 @@ CheckClass::Bool CheckClass::isInverted(const Token *tok, const Token *rhs)
18771877

18781878
const Token * CheckClass::getIfStmtBodyStart(const Token *tok, const Token *rhs)
18791879
{
1880-
const Token *top = tok->astTop();
1880+
const Token *top = tok->astTop(true);
18811881
if (Token::simpleMatch(top->link(), ") {")) {
18821882
switch (isInverted(tok->astParent(), rhs)) {
18831883
case Bool::BAILOUT:
@@ -2522,7 +2522,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member
25222522
return false;
25232523
parent = parent->astParent();
25242524
}
2525-
const Token* const top = lhs->astTop();
2525+
const Token* const top = lhs->astTop(true);
25262526
if (top->isAssignmentOp()) {
25272527
if (Token::simpleMatch(top->astOperand2(), "{") && !top->astOperand2()->previous()->function()) // TODO: check usage in init list
25282528
return false;

lib/checkcondition.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ static std::string innerSmtString(const Token * tok)
856856
{
857857
if (!tok)
858858
return "if";
859-
const Token * top = tok->astTop();
859+
const Token * top = tok->astTop(true);
860860
if (top->str() == "(" && top->astOperand1())
861861
return top->astOperand1()->str();
862862
return top->str();
@@ -1138,7 +1138,7 @@ static std::string conditionString(const Token * tok)
11381138
}
11391139

11401140
static bool isIfConstexpr(const Token* tok) {
1141-
const Token* const top = tok->astTop();
1141+
const Token* const top = tok->astTop(true);
11421142
return Token::simpleMatch(top->astOperand1(), "if") && top->astOperand1()->isConstexpr();
11431143
}
11441144

@@ -1835,7 +1835,7 @@ void CheckCondition::checkDuplicateConditionalAssign()
18351835
continue;
18361836
if (!blockTok->next())
18371837
continue;
1838-
const Token *assignTok = blockTok->next()->astTop();
1838+
const Token *assignTok = blockTok->next()->astTop(true);
18391839
if (!Token::simpleMatch(assignTok, "="))
18401840
continue;
18411841
if (nextAfterAstRightmostLeaf(assignTok) != blockTok->link()->previous())

lib/checkfunctions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ void CheckFunctions::checkLibraryMatchFunctions()
641641
if (tok->function())
642642
continue;
643643

644-
if (Token::simpleMatch(tok->astTop(), "throw"))
644+
if (Token::simpleMatch(tok->astTop(true), "throw"))
645645
continue;
646646

647647
if (Token::simpleMatch(tok->astParent(), ".")) {

lib/checkleakautovar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ void CheckLeakAutoVar::changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocI
985985
var->second.type = allocation.type;
986986
var->second.allocTok = allocation.allocTok;
987987
}
988-
} else if (allocation.status != VarInfo::NOALLOC && allocation.status != VarInfo::OWNED && !Token::simpleMatch(tok->astTop(), "return")) {
988+
} else if (allocation.status != VarInfo::NOALLOC && allocation.status != VarInfo::OWNED && !Token::simpleMatch(tok->astTop(true), "return")) {
989989
auto& allocInfo = alloctype[arg->varId()];
990990
allocInfo.status = VarInfo::DEALLOC;
991991
allocInfo.allocTok = tok;

lib/checkmemoryleak.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope)
10121012
tok2 = tok2->astParent();
10131013
if (Token::Match(tok2, "%assign%")) // TODO: check if function returns allocated resource
10141014
continue;
1015-
if (Token::simpleMatch(tok->astTop(), "return"))
1015+
if (Token::simpleMatch(tok->astTop(true), "return"))
10161016
continue;
10171017

10181018
const std::string& functionName = tok->str();

lib/checkother.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,7 +2241,7 @@ static bool isConstTop(const Token *tok)
22412241
if (!tok->astParent())
22422242
return true;
22432243
if (Token::simpleMatch(tok->astParent(), ";") &&
2244-
Token::Match(tok->astTop()->previous(), "for|if (") && Token::simpleMatch(tok->astTop()->astOperand2(), ";")) {
2244+
Token::Match(tok->astTop(true)->previous(), "for|if (") && Token::simpleMatch(tok->astTop(true)->astOperand2(), ";")) {
22452245
if (Token::simpleMatch(tok->astParent()->astParent(), ";"))
22462246
return tok->astParent()->astOperand2() == tok;
22472247
return tok->astParent()->astOperand1() == tok;
@@ -2272,7 +2272,7 @@ void CheckOther::checkIncompleteStatement()
22722272
continue;
22732273
if (!isConstTop(tok))
22742274
continue;
2275-
if (tok->str() == "," && Token::simpleMatch(tok->astTop()->previous(), "for ("))
2275+
if (tok->str() == "," && Token::simpleMatch(tok->astTop(true)->previous(), "for ("))
22762276
continue;
22772277

22782278
// Do not warn for statement when both lhs and rhs has side effects:
@@ -2540,7 +2540,7 @@ static const Token * getSingleExpressionInBlock(const Token * tok)
25402540
{
25412541
if (!tok)
25422542
return nullptr;
2543-
const Token * top = tok->astTop();
2543+
const Token * top = tok->astTop(true);
25442544
const Token * nextExpression = nextAfterAstRightmostLeaf(top);
25452545
if (!Token::simpleMatch(nextExpression, "; }"))
25462546
return nullptr;

lib/checkstl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,7 +1649,7 @@ static const Token* skipLocalVars(const Token* const tok)
16491649
return skipLocalVars(tok->next());
16501650

16511651
if (tok->isAssignmentOp()) {
1652-
const Token *top = tok->astTop();
1652+
const Token *top = tok->astTop(true);
16531653
const Token *varTok = top->astOperand1();
16541654
const Variable *var = varTok->variable();
16551655
if (!var)
@@ -1667,7 +1667,7 @@ static const Token* skipLocalVars(const Token* const tok)
16671667
static const Token *findInsertValue(const Token *tok, const Token *containerTok, const Token *keyTok, const Settings &settings)
16681668
{
16691669
const Token *startTok = skipLocalVars(tok);
1670-
const Token *top = startTok->astTop();
1670+
const Token *top = startTok->astTop(true);
16711671

16721672
const Token *icontainerTok = nullptr;
16731673
const Token *ikeyTok = nullptr;

lib/forwardanalyzer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ namespace {
610610
// In the middle of a loop structure so bail
611611
return Break(Analyzer::Terminate::Bail);
612612
} else if (tok->str() == ";" && tok->astParent()) {
613-
Token* top = tok->astTop();
613+
Token* top = tok->astTop(true);
614614
if (Token::Match(top->previous(), "for|while (") && Token::simpleMatch(top->link(), ") {")) {
615615
Token* endCond = top->link();
616616
Token* endBlock = endCond->linkAt(1);

0 commit comments

Comments
 (0)