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; diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 83a19c40805..967cd0d2315 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -3723,6 +3723,13 @@ 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() { diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 4e227bfca17..88d1a4b2725 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2207,6 +2207,7 @@ class TestSimplifyTokens : public TestFixture { "for ( i = 0 ; ( i < sz ) && ( sz > 3 ) ; ++ i ) { }\n" "}"; ASSERT_EQUALS(expected, tokenizeAndStringify(code, dinit(TokenizeAndStringifyOptions, $.cpp = false))); + ignore_errout(); } void simplifyKnownVariables49() { // #3691 diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 0798983c079..44a2166cd9b 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -1703,6 +1703,7 @@ class TestTokenizer : public TestFixture { " for ( ; x; )\n" " l1: l2: --x;\n" "}")); + ignore_errout(); // Labels before { ASSERT_EQUALS("void f ( int x ) {\n" @@ -1713,6 +1714,7 @@ class TestTokenizer : public TestFixture { " for ( ; x; )\n" " l1: l2: { -- x; }\n" "}")); + ignore_errout(); // 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" "}")); + ignore_errout(); }