Skip to content
Draft
7 changes: 5 additions & 2 deletions lib/reverseanalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand Down
32 changes: 19 additions & 13 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4966,6 +4966,24 @@ static void valueFlowCondition(const ValuePtr<ConditionHandler>& 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<Condition> parse(const Token* tok, const Settings& /*settings*/) const override {

Expand All @@ -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;
Expand Down
21 changes: 21 additions & 0 deletions test/testnullpointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3710,6 +3710,27 @@ 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());

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() {
Expand Down
1 change: 1 addition & 0 deletions test/testsimplifytokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -1727,6 +1729,7 @@ class TestTokenizer : public TestFixture {
" try { throw 1; }\n"
" catch(...) { --x; }\n"
"}"));
ignore_errout();
}


Expand Down
Loading