Skip to content

Commit aff2cca

Browse files
committed
Fix #12861 Hang in valueFlowCondition() with huge array
1 parent 0fe48ba commit aff2cca

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

lib/token.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ class CPPCHECKLIB Token {
117117
Token* mAstOperand1{};
118118
Token* mAstOperand2{};
119119
Token* mAstParent{};
120+
Token* mAstTop{};
120121

121122
// symbol database information
122123
const Scope* mScope{};
@@ -1557,6 +1558,9 @@ class CPPCHECKLIB Token {
15571558
* @throws InternalError thrown on cyclic dependency
15581559
*/
15591560
void astParent(Token* tok);
1561+
void astTop(Token * tok) {
1562+
mImpl->mAstTop = tok;
1563+
}
15601564

15611565
Token * astOperand1() {
15621566
return mImpl->mAstOperand1;
@@ -1597,13 +1601,19 @@ class CPPCHECKLIB Token {
15971601

15981602
}
15991603
RET_NONNULL Token *astTop() {
1604+
if (mImpl->mAstTop) {
1605+
return mImpl->mAstTop;
1606+
}
16001607
Token *ret = this;
16011608
while (ret->mImpl->mAstParent)
16021609
ret = ret->mImpl->mAstParent;
16031610
return ret;
16041611
}
16051612

16061613
RET_NONNULL const Token *astTop() const {
1614+
if (mImpl->mAstTop) {
1615+
return mImpl->mAstTop;
1616+
}
16071617
const Token *ret = this;
16081618
while (ret->mImpl->mAstParent)
16091619
ret = ret->mImpl->mAstParent;

lib/tokenlist.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,6 +1860,16 @@ void TokenList::createAst() const
18601860
throw InternalError(tok, "Syntax Error: Infinite loop when creating AST.", InternalError::AST);
18611861
tok = nextTok;
18621862
}
1863+
for (Token *tok = mTokensFrontBack->front; tok; tok = tok ? tok->next() : nullptr) {
1864+
if (tok->astParent())
1865+
continue;
1866+
if (!tok->astOperand1() && !tok->astOperand2())
1867+
continue;
1868+
visitAstNodes(tok, [&](Token* child) {
1869+
child->astTop(tok);
1870+
return ChildrenToVisit::op1_and_op2;
1871+
});
1872+
}
18631873
}
18641874

18651875
namespace {

test/cli/performance_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def test_slow_many_scopes(tmpdir):
222222
cppcheck([filename]) # should not take more than ~1 second
223223

224224
@pytest.mark.skipif(sys.platform == 'darwin', reason='GitHub macOS runners are too slow')
225-
@pytest.mark.timeout(20)
225+
@pytest.mark.timeout(15)
226226
def test_crash_array_in_namespace(tmpdir):
227227
# 12847
228228
filename = os.path.join(tmpdir, 'hang.cpp')

0 commit comments

Comments
 (0)