Fix FP with strcmp and terminating conditions

This commit is contained in:
Paul Fultz II 2018-11-27 06:39:29 +01:00 committed by Daniel Marjamäki
parent f2660ed203
commit 5a6f9ac82a
2 changed files with 14 additions and 3 deletions

View File

@ -1171,6 +1171,11 @@ static void valueFlowTerminatingCondition(TokenList *tokenlist, SymbolDatabase*
for (Token* tok = cond.first->next(); tok != scope->bodyEnd; tok = tok->next()) { for (Token* tok = cond.first->next(); tok != scope->bodyEnd; tok = tok->next()) {
if (tok == cond.first) if (tok == cond.first)
continue; continue;
const Token *tokParent = tok->astParent();
while (tokParent && tokParent != cond.first)
tokParent = tokParent->astParent();
if (tokParent == cond.first)
continue;
if (!Token::Match(tok, "%comp%")) if (!Token::Match(tok, "%comp%"))
continue; continue;
// Skip known values // Skip known values

View File

@ -38,6 +38,7 @@ private:
void run() override { void run() override {
LOAD_LIB_2(settings0.library, "qt.cfg"); LOAD_LIB_2(settings0.library, "qt.cfg");
LOAD_LIB_2(settings0.library, "std.cfg");
settings0.addEnabled("style"); settings0.addEnabled("style");
settings0.addEnabled("warning"); settings0.addEnabled("warning");
@ -1991,9 +1992,6 @@ private:
check("void f1(QString s) { if(s.isEmpty()) if(s.length() > 42) {}} "); check("void f1(QString s) { if(s.isEmpty()) if(s.length() > 42) {}} ");
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str()); ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
check("void f1(const std::string &s) { if(s.empty()) if(s.size() == 0) {}} ");
ASSERT_EQUALS("", errout.str());
check("void f1(const std::string &s, bool b) { if(s.empty() || ((s.size() == 1) && b)) {}} "); check("void f1(const std::string &s, bool b) { if(s.empty() || ((s.size() == 1) && b)) {}} ");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
@ -2519,6 +2517,9 @@ private:
"[test.cpp:4]: (style) Condition 'x++==2' is always false\n", "[test.cpp:4]: (style) Condition 'x++==2' is always false\n",
errout.str()); errout.str());
check("void f1(const std::string &s) { if(s.empty()) if(s.size() == 0) {}} ");
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (style) Condition 's.size()==0' is always true\n", errout.str());
// Avoid FP when condition comes from macro // Avoid FP when condition comes from macro
check("#define NOT !\n" check("#define NOT !\n"
"void f() {\n" "void f() {\n"
@ -2703,6 +2704,11 @@ private:
" }\n" " }\n"
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(const char* x, const char* t) {\n"
" if (!(strcmp(x, y) == 0)) { return; }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void multiConditionAlwaysTrue() { void multiConditionAlwaysTrue() {