From 08c34af4a4cd8ed8f385ee5b629e101b1feccd3b Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:15:34 +0200 Subject: [PATCH 01/10] Update reverseanalyzer.cpp --- lib/reverseanalyzer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 50aad01fdd9..4afd2556a24 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -110,8 +110,11 @@ namespace { { if (Token::simpleMatch(tok->tokAt(-2), "} else {")) tok = tok->linkAt(-2); - if (Token::simpleMatch(tok->previous(), ") {")) + if (Token::simpleMatch(tok->previous(), ") {")) { + if (Token::simpleMatch(tok->linkAt(-1)->astOperand2(), ";")) + return tok->linkAt(-1)->astOperand2(); return tok->linkAt(-1); + } if (Token::simpleMatch(tok->previous(), "do {")) return tok->previous(); return tok; @@ -232,7 +235,7 @@ namespace { if (!Token::Match(assignTop->astOperand1(), "%assign%")) { continueB &= updateRecursive(assignTop->astOperand1()); } - if (!assignTop->astParent()) + if (!assignTop->astParent() || Token::simpleMatch(assignTop->astParent(), ";")) break; assignTop = assignTop->astParent(); } From bc83d1c24ded9befaefe6dfe216d9e04b60e168a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:22:42 +0200 Subject: [PATCH 02/10] Update testnullpointer.cpp --- test/testnullpointer.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index a9ce5ff6f38..83a19c40805 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -3710,6 +3710,19 @@ class TestNullPointer : public TestFixture { " i++;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f(const int* p) {\n" // #6710 + " for (int i = *p; i < 5; ++i) {}\n" + " if (p) {}\n" + "}\n" + "struct S { int a; };\n" + "void g(const S* s) {\n" + " for (int i = s->a; i < 5; ++i) {}\n" + " if (s) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:19]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n" + "[test.cpp:8:9] -> [test.cpp:7:18]: (warning) Either the condition 's' is redundant or there is possible null pointer dereference: s. [nullPointerRedundantCheck]\n", + errout_str()); } void nullpointerDeadCode() { From 0e75bba758e83354c34f33a5d3dc791fd656ba7c Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 16:16:50 +0200 Subject: [PATCH 03/10] Update valueflow.cpp --- lib/valueflow.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 74763fde027..cc71510df9e 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4966,6 +4966,24 @@ static void valueFlowCondition(const ValuePtr& handler, handler->afterCondition(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions); } +static const Token* getConditionVariable(const Token* tok) +{ + if (tok->str() == "!") + return tok->astOperand1(); + + if (const Token* parent = tok->astParent()) { + if (Token::Match(parent, "%oror%|&&|?") || + Token::Match(parent->previous(), "if|while (") || + (parent->str() == ";" && Token::simpleMatch(parent->astParent(), ";"))) { + if (Token::simpleMatch(tok, "=")) + return tok->astOperand1(); + if (!Token::Match(tok, "%comp%|%assign%")) + return tok; + } + } + return nullptr; +} + struct SimpleConditionHandler : ConditionHandler { std::vector parse(const Token* tok, const Settings& /*settings*/) const override { @@ -4984,19 +5002,7 @@ struct SimpleConditionHandler : ConditionHandler { if (!conds.empty()) return conds; - const Token* vartok = nullptr; - - if (tok->str() == "!") { - vartok = tok->astOperand1(); - - } else if (tok->astParent() && (Token::Match(tok->astParent(), "%oror%|&&|?") || - Token::Match(tok->astParent()->previous(), "if|while ("))) { - if (Token::simpleMatch(tok, "=")) - vartok = tok->astOperand1(); - else if (!Token::Match(tok, "%comp%|%assign%")) - vartok = tok; - } - + const Token* vartok = getConditionVariable(tok); if (!vartok) return {}; Condition cond; From aace0235d8c8390d25845c2601b0c80706232194 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 16:17:55 +0200 Subject: [PATCH 04/10] Update testnullpointer.cpp --- test/testnullpointer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 83a19c40805..d489437e7cf 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -3723,6 +3723,14 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("[test.cpp:3:9] -> [test.cpp:2:19]: (warning) Either the condition 'p' is redundant or there is possible null pointer dereference: p. [nullPointerRedundantCheck]\n" "[test.cpp:8:9] -> [test.cpp:7:18]: (warning) Either the condition 's' is redundant or there is possible null pointer dereference: s. [nullPointerRedundantCheck]\n", errout_str()); + + check("struct S { int a; };\n" // #6492 + "void h(const S* s) {\n" + " for (int i = s->a; s; ++i) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:24] -> [test.cpp:3:18]: (warning) Either the condition 's' is redundant or there is possible null pointer dereference: s. [nullPointerRedundantCheck]\n", + errout_str()); + } void nullpointerDeadCode() { From 2c99d0bf1a82c46e6a3d0be9b2081b9f26fc8107 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 16:18:32 +0200 Subject: [PATCH 05/10] Update testsimplifytokens.cpp --- test/testsimplifytokens.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 4e227bfca17..feca024abc8 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2207,6 +2207,9 @@ class TestSimplifyTokens : public TestFixture { "for ( i = 0 ; ( i < sz ) && ( sz > 3 ) ; ++ i ) { }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, dinit(TokenizeAndStringifyOptions, $.cpp = false))); + ASSERT_EQUALS("[test.c:3:25]: (debug) valueflow.cpp:4550:(valueFlow) bailout: variable '(i3)' used in loop [valueFlowBailout]\n" + "[test.c:3:25]: (debug) valueflow.cpp:4550:(valueFlow) bailout: variable '(i3)' used in loop [valueFlowBailout]\n", + errout_str()); } void simplifyKnownVariables49() { // #3691 From 3145747ffbe02530ce072a03ce4069e437b67b11 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 16:19:10 +0200 Subject: [PATCH 06/10] Update testtokenize.cpp --- test/testtokenize.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 0798983c079..9fdfd72e2b5 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -1703,6 +1703,7 @@ class TestTokenizer : public TestFixture { " for ( ; x; )\n" " l1: l2: --x;\n" "}")); + ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4574:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); // Labels before { ASSERT_EQUALS("void f ( int x ) {\n" @@ -1713,6 +1714,7 @@ class TestTokenizer : public TestFixture { " for ( ; x; )\n" " l1: l2: { -- x; }\n" "}")); + ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4574:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); // Labels before try/catch ASSERT_EQUALS("void f ( int x ) {\n" @@ -1727,6 +1729,7 @@ class TestTokenizer : public TestFixture { " try { throw 1; }\n" " catch(...) { --x; }\n" "}")); + ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4574:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); } From b70147ab2f5383e56bbacea8536e44dc97d1de5e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 16:52:44 +0200 Subject: [PATCH 07/10] Update testsimplifytokens.cpp [skip ci] --- test/testsimplifytokens.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index feca024abc8..11ff1006be0 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2207,8 +2207,8 @@ class TestSimplifyTokens : public TestFixture { "for ( i = 0 ; ( i < sz ) && ( sz > 3 ) ; ++ i ) { }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, dinit(TokenizeAndStringifyOptions, $.cpp = false))); - ASSERT_EQUALS("[test.c:3:25]: (debug) valueflow.cpp:4550:(valueFlow) bailout: variable '(i3)' used in loop [valueFlowBailout]\n" - "[test.c:3:25]: (debug) valueflow.cpp:4550:(valueFlow) bailout: variable '(i3)' used in loop [valueFlowBailout]\n", + ASSERT_EQUALS("[test.c:3:25]: (debug) valueflow.cpp:4547:(valueFlow) bailout: variable '(i3)' used in loop [valueFlowBailout]\n" + "[test.c:3:25]: (debug) valueflow.cpp:4547:(valueFlow) bailout: variable '(i3)' used in loop [valueFlowBailout]\n", errout_str()); } From afc61d1e094a48665e504f0e71b50694e73cd3c0 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 16:54:08 +0200 Subject: [PATCH 08/10] Update testtokenize.cpp --- test/testtokenize.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 9fdfd72e2b5..cfcb44254b3 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -1703,7 +1703,7 @@ class TestTokenizer : public TestFixture { " for ( ; x; )\n" " l1: l2: --x;\n" "}")); - ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4574:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4571:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); // Labels before { ASSERT_EQUALS("void f ( int x ) {\n" @@ -1714,7 +1714,7 @@ class TestTokenizer : public TestFixture { " for ( ; x; )\n" " l1: l2: { -- x; }\n" "}")); - ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4574:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4571:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); // Labels before try/catch ASSERT_EQUALS("void f ( int x ) {\n" @@ -1729,7 +1729,7 @@ class TestTokenizer : public TestFixture { " try { throw 1; }\n" " catch(...) { --x; }\n" "}")); - ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4574:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4571:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); } From 6e4cc8bf45d975605f1bf5aff280af99ef884fab Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 17:13:34 +0200 Subject: [PATCH 09/10] Update testsimplifytokens.cpp [skip ci] --- test/testsimplifytokens.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 11ff1006be0..88d1a4b2725 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2207,9 +2207,7 @@ class TestSimplifyTokens : public TestFixture { "for ( i = 0 ; ( i < sz ) && ( sz > 3 ) ; ++ i ) { }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, dinit(TokenizeAndStringifyOptions, $.cpp = false))); - ASSERT_EQUALS("[test.c:3:25]: (debug) valueflow.cpp:4547:(valueFlow) bailout: variable '(i3)' used in loop [valueFlowBailout]\n" - "[test.c:3:25]: (debug) valueflow.cpp:4547:(valueFlow) bailout: variable '(i3)' used in loop [valueFlowBailout]\n", - errout_str()); + ignore_errout(); } void simplifyKnownVariables49() { // #3691 From fc8374b2597926d6da47b0b3fc88e70fbb4567fd Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Apr 2026 17:14:42 +0200 Subject: [PATCH 10/10] Update testtokenize.cpp --- test/testtokenize.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index cfcb44254b3..44a2166cd9b 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -1703,7 +1703,7 @@ class TestTokenizer : public TestFixture { " for ( ; x; )\n" " l1: l2: --x;\n" "}")); - ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4571:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); + ignore_errout(); // Labels before { ASSERT_EQUALS("void f ( int x ) {\n" @@ -1714,7 +1714,7 @@ class TestTokenizer : public TestFixture { " for ( ; x; )\n" " l1: l2: { -- x; }\n" "}")); - ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4571:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); + ignore_errout(); // Labels before try/catch ASSERT_EQUALS("void f ( int x ) {\n" @@ -1729,7 +1729,7 @@ class TestTokenizer : public TestFixture { " try { throw 1; }\n" " catch(...) { --x; }\n" "}")); - ASSERT_EQUALS("[test.cpp:2:11]: (debug) valueflow.cpp:4571:(valueFlow) bailout: variable 'x' used in loop [valueFlowBailout]\n", errout_str()); + ignore_errout(); }