From 02fed7a2663d619877812b63de135ba9490364a4 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 15 Dec 2023 11:01:08 +0100 Subject: [PATCH] Fix #12235 performance regression (hang) in 2.13dev (#5715) Co-authored-by: chrchr-github --- lib/astutils.cpp | 4 +++- test/cli/test-performance.py | 40 +++++++++++++++++++++++++++++++++++- test/testastutils.cpp | 2 ++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index be0939b86..81e945565 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2767,8 +2767,10 @@ static bool isExpressionChangedAt(const F& getExprTok, { if (depth < 0) return true; + if (tok->isLiteral() || tok->isKeyword() || tok->isStandardType() || Token::Match(tok, ",|;|:")) + return false; if (tok->exprId() != exprid) { - if (globalvar && !tok->isKeyword() && Token::Match(tok, "%name% (") && !(tok->function() && tok->function()->isAttributePure())) + if (globalvar && Token::Match(tok, "%name% (") && !(tok->function() && tok->function()->isAttributePure())) // TODO: Is global variable really changed by function call? return true; int i = 1; diff --git a/test/cli/test-performance.py b/test/cli/test-performance.py index 305994869..1e7cd38f3 100644 --- a/test/cli/test-performance.py +++ b/test/cli/test-performance.py @@ -146,4 +146,42 @@ int foo(int a, int b) cppcheck([filename], env=my_env) - +@pytest.mark.timeout(10) +def test_slow_initlist_varchanged(tmpdir): + # #12235 + filename = os.path.join(tmpdir, 'hang.cpp') + with open(filename, 'wt') as f: + f.write(r""" + struct T { + int* q; + int nx, ny; + }; + struct S { + void f(); + int n; + T* p; + }; + #define ROW 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , + #define ROW4 ROW ROW ROW ROW + #define ROW16 ROW4 ROW4 ROW4 ROW4 + #define ROW64 ROW16 ROW16 ROW16 ROW16 + #define ROW256 ROW64 ROW64 ROW64 ROW64 + #define ROW1K ROW256 ROW256 ROW256 ROW256 + #define ROW4K ROW1K ROW1K ROW1K ROW1K + const int A[] = { + ROW4K + }; + void S::f() { + for (int i = 0; i < n; ++i) { + T& t = p[i]; + for (int y = 0; y < t.ny; y += 4) { + int* row0 = t.q + y * t.nx; + for (int x = 0; x < t.nx; x += 4) { + int s[16] = {}; + memcpy(row0, &s[0], 4); + row0 += 4; + } + } + } + }""") + cppcheck([filename]) # should not take more than ~1 second diff --git a/test/testastutils.cpp b/test/testastutils.cpp index eacaaace8..d6ba495b4 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -243,6 +243,8 @@ private: "void f(int x) { g(&x); }\n", "{", "}")); + + ASSERT_EQUALS(false, isVariableChanged("const int A[] = { 1, 2, 3 };", "[", "]")); } #define isVariableChangedByFunctionCall(code, pattern, inconclusive) isVariableChangedByFunctionCall_(code, pattern, inconclusive, __FILE__, __LINE__)