diff --git a/lib/token.h b/lib/token.h index 5fddf510b19..d26c7ac7640 100644 --- a/lib/token.h +++ b/lib/token.h @@ -117,6 +117,7 @@ class CPPCHECKLIB Token { Token* mAstOperand1{}; Token* mAstOperand2{}; Token* mAstParent{}; + Token* mAstTop{}; // symbol database information const Scope* mScope{}; @@ -1557,6 +1558,9 @@ class CPPCHECKLIB Token { * @throws InternalError thrown on cyclic dependency */ void astParent(Token* tok); + void astTop(Token * tok) { + mImpl->mAstTop = tok; + } Token * astOperand1() { return mImpl->mAstOperand1; @@ -1597,6 +1601,9 @@ class CPPCHECKLIB Token { } RET_NONNULL Token *astTop() { + if (mImpl->mAstTop) { + return mImpl->mAstTop; + } Token *ret = this; while (ret->mImpl->mAstParent) ret = ret->mImpl->mAstParent; @@ -1604,6 +1611,9 @@ class CPPCHECKLIB Token { } RET_NONNULL const Token *astTop() const { + if (mImpl->mAstTop) { + return mImpl->mAstTop; + } const Token *ret = this; while (ret->mImpl->mAstParent) ret = ret->mImpl->mAstParent; diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 1e476a14ec5..7fccbb89f1d 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1860,6 +1860,16 @@ void TokenList::createAst() const throw InternalError(tok, "Syntax Error: Infinite loop when creating AST.", InternalError::AST); tok = nextTok; } + for (Token *tok = mTokensFrontBack->front; tok; tok = tok ? tok->next() : nullptr) { + if (tok->astParent()) + continue; + if (!tok->astOperand1() && !tok->astOperand2()) + continue; + visitAstNodes(tok, [&](Token* child) { + child->astTop(tok); + return ChildrenToVisit::op1_and_op2; + }); + } } namespace { diff --git a/test/cli/performance_test.py b/test/cli/performance_test.py index 9f5141f2bb9..c7ebc02a9ac 100644 --- a/test/cli/performance_test.py +++ b/test/cli/performance_test.py @@ -222,7 +222,7 @@ def test_slow_many_scopes(tmpdir): cppcheck([filename]) # should not take more than ~1 second @pytest.mark.skipif(sys.platform == 'darwin', reason='GitHub macOS runners are too slow') -@pytest.mark.timeout(20) +@pytest.mark.timeout(15) def test_crash_array_in_namespace(tmpdir): # 12847 filename = os.path.join(tmpdir, 'hang.cpp')