diff --git a/lib/executionpath.cpp b/lib/executionpath.cpp index 7e8b6c4c7..774b9c28d 100644 --- a/lib/executionpath.cpp +++ b/lib/executionpath.cpp @@ -275,6 +275,40 @@ void ExecutionPath::checkScope(const Token *tok, std::list &che ++it; } + // #2231 - loop body only contains a conditional initialization.. + if (Token::simpleMatch(tok2->next(), "if (")) + { + // Start { for the if block + const Token *tok3 = tok2->tokAt(2)->link(); + if (Token::simpleMatch(tok3,") {")) + { + tok3 = tok3->next(); + + // End } for the if block + const Token *tok4 = tok3->link(); + if (Token::Match(tok3, "{ %var% =") && + Token::simpleMatch(tok4, "} }") && + Token::simpleMatch(tok4->tokAt(-2), "break ;")) + { + // Is there a assignment and then a break? + const Token *t = Token::findmatch(tok3, ";"); + if (t && t->tokAt(3) == tok4) + { + for (std::list::iterator it = checks.begin(); it != checks.end(); ++it) + { + if ((*it)->varId == tok3->next()->varId()) + { + (*it)->numberOfIf++; + break; + } + } + tok = tok2->link(); + continue; + } + } + } + } + // parse loop bodies check->parseLoopBody(tok2->next(), checks); } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 03a7d0e1b..82f108fac 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -718,6 +718,21 @@ private: "}\n"); TODO_ASSERT_EQUALS("error", "", errout.str()); + + // #2231 - error if assignment in loop is not used + check("void f() {\n" + " char *p = 0;\n" + "\n" + " for (int x = 0; x < 3; ++x) {\n" + " if (y[x] == 0) {\n" + " p = malloc(10);\n" + " break;\n" + " }\n" + " }\n" + "\n" + " *p = 0;\n" + "}"); + ASSERT_EQUALS("[test.cpp:11]: (error) Possible null pointer dereference: p\n", errout.str()); } void nullpointer7() diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 1aee1c480..fbd29681d 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -801,6 +801,21 @@ private: "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: pItem\n", "", errout.str()); + + // #2231 - conditional initialization in loop.. + checkUninitVar("int foo(char *a) {\n" + " int x;\n" + "\n" + " for (int i = 0; i < 10; ++i) {\n" + " if (a[i] == 'x') {\n" + " x = i;\n" + " break;\n" + " }\n" + " }\n" + "\n" + " return x;\n" + "}"); + ASSERT_EQUALS("[test.cpp:11]: (error) Uninitialized variable: x\n", errout.str()); } // switch..