Skip to content

Commit 02fed7a

Browse files
chrchr-githubchrchr-github
andauthored
Fix #12235 performance regression (hang) in 2.13dev (#5715)
Co-authored-by: chrchr-github <chrchr@github>
1 parent 61bbcbe commit 02fed7a

3 files changed

Lines changed: 44 additions & 2 deletions

File tree

lib/astutils.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2767,8 +2767,10 @@ static bool isExpressionChangedAt(const F& getExprTok,
27672767
{
27682768
if (depth < 0)
27692769
return true;
2770+
if (tok->isLiteral() || tok->isKeyword() || tok->isStandardType() || Token::Match(tok, ",|;|:"))
2771+
return false;
27702772
if (tok->exprId() != exprid) {
2771-
if (globalvar && !tok->isKeyword() && Token::Match(tok, "%name% (") && !(tok->function() && tok->function()->isAttributePure()))
2773+
if (globalvar && Token::Match(tok, "%name% (") && !(tok->function() && tok->function()->isAttributePure()))
27722774
// TODO: Is global variable really changed by function call?
27732775
return true;
27742776
int i = 1;

test/cli/test-performance.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,42 @@ def test_slow_exprid(tmpdir):
146146
cppcheck([filename], env=my_env)
147147

148148

149-
149+
@pytest.mark.timeout(10)
150+
def test_slow_initlist_varchanged(tmpdir):
151+
# #12235
152+
filename = os.path.join(tmpdir, 'hang.cpp')
153+
with open(filename, 'wt') as f:
154+
f.write(r"""
155+
struct T {
156+
int* q;
157+
int nx, ny;
158+
};
159+
struct S {
160+
void f();
161+
int n;
162+
T* p;
163+
};
164+
#define ROW 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ,
165+
#define ROW4 ROW ROW ROW ROW
166+
#define ROW16 ROW4 ROW4 ROW4 ROW4
167+
#define ROW64 ROW16 ROW16 ROW16 ROW16
168+
#define ROW256 ROW64 ROW64 ROW64 ROW64
169+
#define ROW1K ROW256 ROW256 ROW256 ROW256
170+
#define ROW4K ROW1K ROW1K ROW1K ROW1K
171+
const int A[] = {
172+
ROW4K
173+
};
174+
void S::f() {
175+
for (int i = 0; i < n; ++i) {
176+
T& t = p[i];
177+
for (int y = 0; y < t.ny; y += 4) {
178+
int* row0 = t.q + y * t.nx;
179+
for (int x = 0; x < t.nx; x += 4) {
180+
int s[16] = {};
181+
memcpy(row0, &s[0], 4);
182+
row0 += 4;
183+
}
184+
}
185+
}
186+
}""")
187+
cppcheck([filename]) # should not take more than ~1 second

test/testastutils.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ class TestAstUtils : public TestFixture {
243243
"void f(int x) { g(&x); }\n",
244244
"{",
245245
"}"));
246+
247+
ASSERT_EQUALS(false, isVariableChanged("const int A[] = { 1, 2, 3 };", "[", "]"));
246248
}
247249

248250
#define isVariableChangedByFunctionCall(code, pattern, inconclusive) isVariableChangedByFunctionCall_(code, pattern, inconclusive, __FILE__, __LINE__)

0 commit comments

Comments
 (0)