Fix FP with strcmp and terminating conditions
This commit is contained in:
parent
f2660ed203
commit
5a6f9ac82a
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue