This commit is contained in:
parent
bddc698295
commit
9cbfa0e383
|
@ -1151,12 +1151,6 @@ void CheckCondition::alwaysTrueFalse()
|
|||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
|
||||
const bool constValCond = Token::Match(tok->tokAt(-2), "if|while ( %num%|%char% )") && !Token::Match(tok,"0|1"); // just one number or char inside if|while
|
||||
const bool constValExpr = Token::Match(tok, "%num%|%char%") && tok->astParent() && Token::Match(tok->astParent(),"&&|%oror%|?"); // just one number or char in boolean expression
|
||||
const bool compExpr = Token::Match(tok, "%comp%|!"); // a compare expression
|
||||
|
||||
if (!(constValCond || constValExpr || compExpr))
|
||||
continue;
|
||||
if (tok->link()) // don't write false positives when templates are used
|
||||
continue;
|
||||
if (!tok->hasKnownIntValue())
|
||||
|
@ -1164,6 +1158,16 @@ void CheckCondition::alwaysTrueFalse()
|
|||
if (Token::Match(tok, "[01]"))
|
||||
continue;
|
||||
|
||||
const bool constIfWhileExpression =
|
||||
tok->astParent()
|
||||
&& Token::Match(tok->astParent()->astOperand1(), "if|while")
|
||||
&& !tok->isBoolean();
|
||||
const bool constValExpr = Token::Match(tok, "%num%|%char%") && tok->astParent() && Token::Match(tok->astParent(),"&&|%oror%|?"); // just one number or char in boolean expression
|
||||
const bool compExpr = Token::Match(tok, "%comp%|!"); // a compare expression
|
||||
|
||||
if (!(constIfWhileExpression || constValExpr || compExpr))
|
||||
continue;
|
||||
|
||||
// Don't warn in assertions. Condition is often 'always true' by intention.
|
||||
// If platform,defines,etc cause 'always false' then that is not dangerous neither.
|
||||
bool assertFound = false;
|
||||
|
|
|
@ -97,6 +97,7 @@ private:
|
|||
TEST_CASE(alwaysTrue);
|
||||
|
||||
TEST_CASE(checkInvalidTestForOverflow);
|
||||
TEST_CASE(checkConditionIsAlwaysTrueOrFalseInsideIfWhile);
|
||||
}
|
||||
|
||||
void check(const char code[], const char* filename = "test.cpp", bool inconclusive = false) {
|
||||
|
@ -355,7 +356,7 @@ private:
|
|||
" g(x);\n"
|
||||
" }\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'x' is always true\n", errout.str());
|
||||
|
||||
check("void g(int & x);\n"
|
||||
"void f() {\n"
|
||||
|
@ -1935,6 +1936,7 @@ private:
|
|||
" if (x & 3 == 2) {}\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Suspicious condition (bitwise operator + comparison); Clarify expression with parentheses.\n"
|
||||
"[test.cpp:2]: (style) Condition 'x&3==2' is always false\n"
|
||||
"[test.cpp:2]: (style) Condition '3==2' is always false\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
|
@ -2153,6 +2155,7 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Condition ''a'' is always true\n"
|
||||
"[test.cpp:3]: (style) Condition 'L'b'' is always true\n"
|
||||
"[test.cpp:4]: (style) Condition '1&&'c'' is always true\n"
|
||||
"[test.cpp:4]: (style) Condition ''c'' is always true\n"
|
||||
"[test.cpp:5]: (style) Condition ''d'' is always true\n", errout.str());
|
||||
}
|
||||
|
@ -2188,6 +2191,33 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void checkConditionIsAlwaysTrueOrFalseInsideIfWhile() {
|
||||
check("void f() {\n"
|
||||
" enum states {A,B,C};\n"
|
||||
" const unsigned g_flags = B|C;\n"
|
||||
" if(g_flags & A) {}\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'g_flags&A' is always false\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" int a = 5;"
|
||||
" if(a) {}\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'a' is always true\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" int a = 5;"
|
||||
" while(a + 1) { a--; }\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" int a = 5;"
|
||||
" while(a + 1) { return; }\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'a+1' is always true\n", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestCondition)
|
||||
|
|
Loading…
Reference in New Issue