Skip to content

Commit 3ae4054

Browse files
committed
Fix #12861 Hang in valueFlowCondition() with huge array
1 parent 4617bc2 commit 3ae4054

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed

lib/token.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,10 @@ std::string Token::stringifyList(bool varid) const
14121412
return stringifyList(varid, false, true, true, true, nullptr, nullptr);
14131413
}
14141414

1415+
void Token::astTop(Token * tok) {
1416+
mImpl->mAstTop = tok;
1417+
}
1418+
14151419
void Token::astParent(Token* tok)
14161420
{
14171421
const Token* tok2 = tok;

lib/token.h

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct TokenImpl {
8888
Token* mAstOperand1{};
8989
Token* mAstOperand2{};
9090
Token* mAstParent{};
91+
Token* mAstTop{};
9192

9293
// symbol database information
9394
const Scope* mScope{};
@@ -1492,6 +1493,7 @@ class CPPCHECKLIB Token {
14921493
void astOperand1(Token *tok);
14931494
void astOperand2(Token *tok);
14941495
void astParent(Token* tok);
1496+
void astTop(Token* tok);
14951497

14961498
Token * astOperand1() {
14971499
return mImpl->mAstOperand1;
@@ -1511,6 +1513,31 @@ class CPPCHECKLIB Token {
15111513
const Token * astParent() const {
15121514
return mImpl->mAstParent;
15131515
}
1516+
Token * astTop() {
1517+
Token *ret = this;
1518+
if (ret->mImpl->mAstTop) {
1519+
return ret->mImpl->mAstTop;
1520+
} else {
1521+
if (ret->mImpl->mAstParent) {
1522+
return ret->mImpl->mAstParent->astTop();
1523+
} else {
1524+
return ret;
1525+
}
1526+
}
1527+
}
1528+
const Token * astTop() const {
1529+
const Token *ret = this;
1530+
if (ret->mImpl->mAstTop) {
1531+
return ret->mImpl->mAstTop;
1532+
} else {
1533+
if (ret->mImpl->mAstParent) {
1534+
return ret->mImpl->mAstParent->astTop();
1535+
} else {
1536+
return ret;
1537+
}
1538+
}
1539+
}
1540+
15141541
Token * astSibling() {
15151542
if (!astParent())
15161543
return nullptr;
@@ -1531,19 +1558,6 @@ class CPPCHECKLIB Token {
15311558
return nullptr;
15321559

15331560
}
1534-
RET_NONNULL Token *astTop() {
1535-
Token *ret = this;
1536-
while (ret->mImpl->mAstParent)
1537-
ret = ret->mImpl->mAstParent;
1538-
return ret;
1539-
}
1540-
1541-
RET_NONNULL const Token *astTop() const {
1542-
const Token *ret = this;
1543-
while (ret->mImpl->mAstParent)
1544-
ret = ret->mImpl->mAstParent;
1545-
return ret;
1546-
}
15471561

15481562
std::pair<const Token *, const Token *> findExpressionStartEndTokens() const;
15491563

lib/tokenize.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3423,6 +3423,15 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration, int fileIndex)
34233423

34243424
if (!mSettings.buildDir.empty())
34253425
Summaries::create(*this, configuration, fileIndex);
3426+
Token * it_tok = list.front();
3427+
while(it_tok) {
3428+
if (it_tok->astParent()) {
3429+
it_tok->astTop(it_tok->astParent()->astTop());
3430+
} else {
3431+
it_tok->astTop(it_tok);
3432+
}
3433+
it_tok = it_tok->next();
3434+
}
34263435

34273436
// TODO: apply this through Settings::ValueFlowOptions
34283437
// TODO: do not run valueflow if no checks are being performed at all - e.g. unusedFunctions only

0 commit comments

Comments
 (0)