errmsg: Added 'condition is always true/false'
This commit is contained in:
parent
22583269c1
commit
03cfe18c9b
|
@ -194,87 +194,92 @@ void CheckOther::redundantCondition2()
|
||||||
|
|
||||||
void CheckOther::WarningIf()
|
void CheckOther::WarningIf()
|
||||||
{
|
{
|
||||||
// Search for 'if (condition);'
|
if (ErrorMessage::ifNoAction(_settings))
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
|
||||||
{
|
{
|
||||||
if (!Token::simpleMatch(tok, "if ("))
|
// Search for 'if (condition);'
|
||||||
continue;
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||||
|
|
||||||
// Search for the end paranthesis for the condition..
|
|
||||||
int parlevel = 0;
|
|
||||||
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next())
|
|
||||||
{
|
{
|
||||||
if (tok2->str() == "(")
|
if (!Token::simpleMatch(tok, "if ("))
|
||||||
++parlevel;
|
continue;
|
||||||
else if (tok2->str() == ")")
|
|
||||||
|
// Search for the end paranthesis for the condition..
|
||||||
|
int parlevel = 0;
|
||||||
|
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next())
|
||||||
{
|
{
|
||||||
--parlevel;
|
if (tok2->str() == "(")
|
||||||
if (parlevel <= 0)
|
++parlevel;
|
||||||
|
else if (tok2->str() == ")")
|
||||||
{
|
{
|
||||||
if (Token::Match(tok2, ") ; !!else"))
|
--parlevel;
|
||||||
|
if (parlevel <= 0)
|
||||||
{
|
{
|
||||||
_errorLogger->reportErr(ErrorMessage::ifNoAction(_tokenizer, tok));
|
if (Token::Match(tok2, ") ; !!else"))
|
||||||
|
{
|
||||||
|
_errorLogger->reportErr(ErrorMessage::ifNoAction(_tokenizer, tok));
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for 'a=b; if (a==b)'
|
if (ErrorMessage::conditionAlwaysTrueFalse(_settings))
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
|
||||||
{
|
{
|
||||||
// Begin statement?
|
// Search for 'a=b; if (a==b)'
|
||||||
if (! Token::Match(tok, "[;{}]"))
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||||
continue;
|
|
||||||
tok = tok->next();
|
|
||||||
if (! tok)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!Token::Match(tok, "%var% = %var% ; if ( %var%"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strcmp(tok->strAt(9), ")") != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// var1 = var2 ; if ( var3 cond var4 )
|
|
||||||
const char *var1 = tok->strAt(0);
|
|
||||||
const char *var2 = tok->strAt(2);
|
|
||||||
const char *var3 = tok->strAt(6);
|
|
||||||
const char *cond = tok->strAt(7);
|
|
||||||
const char *var4 = tok->strAt(8);
|
|
||||||
|
|
||||||
// Check that var3 is equal with either var1 or var2
|
|
||||||
if (strcmp(var1, var3) && strcmp(var2, var3))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Check that var4 is equal with either var1 or var2
|
|
||||||
if (strcmp(var1, var4) && strcmp(var2, var4))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Check that there is a condition..
|
|
||||||
const char *p[6] = {"==", "<=", ">=", "!=", "<", ">"};
|
|
||||||
bool iscond = false;
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
{
|
||||||
if (strcmp(cond, p[i]) == 0)
|
// Begin statement?
|
||||||
{
|
if (! Token::Match(tok, "[;{}]"))
|
||||||
iscond = true;
|
continue;
|
||||||
|
tok = tok->next();
|
||||||
|
if (! tok)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!iscond)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// we found the error. Report.
|
if (!Token::Match(tok, "%var% = %var% ; if ( %var%"))
|
||||||
std::ostringstream ostr;
|
continue;
|
||||||
ostr << _tokenizer->fileLine(tok->tokAt(4)) << ": The condition is always ";
|
|
||||||
for (int i = 0; i < 6; i++)
|
if (strcmp(tok->strAt(9), ")") != 0)
|
||||||
{
|
continue;
|
||||||
if (strcmp(cond, p[i]) == 0)
|
|
||||||
ostr << (i < 3 ? "True" : "False");
|
// var1 = var2 ; if ( var3 cond var4 )
|
||||||
|
const char *var1 = tok->strAt(0);
|
||||||
|
const char *var2 = tok->strAt(2);
|
||||||
|
const char *var3 = tok->strAt(6);
|
||||||
|
const char *cond = tok->strAt(7);
|
||||||
|
const char *var4 = tok->strAt(8);
|
||||||
|
|
||||||
|
// Check that var3 is equal with either var1 or var2
|
||||||
|
if (strcmp(var1, var3) && strcmp(var2, var3))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check that var4 is equal with either var1 or var2
|
||||||
|
if (strcmp(var1, var4) && strcmp(var2, var4))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check that there is a condition..
|
||||||
|
const char *p[6] = {"==", "<=", ">=", "!=", "<", ">"};
|
||||||
|
bool iscond = false;
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(cond, p[i]) == 0)
|
||||||
|
{
|
||||||
|
iscond = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!iscond)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// we found the error. Report.
|
||||||
|
bool b = false;
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(cond, p[i]) == 0)
|
||||||
|
b = (i < 3);
|
||||||
|
}
|
||||||
|
_errorLogger->reportErr(ErrorMessage::conditionAlwaysTrueFalse(_tokenizer, tok->tokAt(4), b ? "True" : "False"));
|
||||||
}
|
}
|
||||||
_errorLogger->reportErr(ostr.str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -313,7 +313,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
|
||||||
checkClass.operatorEq();
|
checkClass.operatorEq();
|
||||||
|
|
||||||
// if (condition);
|
// if (condition);
|
||||||
if (ErrorMessage::ifNoAction(_settings))
|
if (ErrorMessage::ifNoAction(_settings) || ErrorMessage::conditionAlwaysTrueFalse(_settings))
|
||||||
checkOther.WarningIf();
|
checkOther.WarningIf();
|
||||||
|
|
||||||
// Unused struct members..
|
// Unused struct members..
|
||||||
|
|
|
@ -318,5 +318,14 @@ public:
|
||||||
return s._checkCodingStyle;
|
return s._checkCodingStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string conditionAlwaysTrueFalse(const Tokenizer *tokenizer, const Token *Location, const std::string &truefalse)
|
||||||
|
{
|
||||||
|
return msg1(tokenizer, Location) + "Condition is always " + truefalse + "";
|
||||||
|
}
|
||||||
|
static bool conditionAlwaysTrueFalse(const Settings &s)
|
||||||
|
{
|
||||||
|
return s._checkCodingStyle;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -160,7 +160,7 @@ private:
|
||||||
"\n"
|
"\n"
|
||||||
"private:\n"
|
"private:\n"
|
||||||
" ECODES _code;\n"
|
" ECODES _code;\n"
|
||||||
"};\n" );
|
"};\n");
|
||||||
|
|
||||||
ASSERT_EQUALS("[test.cpp:10]: Uninitialized member variable 'Fred::_code'\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:10]: Uninitialized member variable 'Fred::_code'\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ int main()
|
||||||
err.push_back(Message("charBitOp", Message::style, "Warning - using char variable in bit operation"));
|
err.push_back(Message("charBitOp", Message::style, "Warning - using char variable in bit operation"));
|
||||||
err.push_back(Message("variableScope", Message::never, "The scope of the variable %1 can be limited", "varname"));
|
err.push_back(Message("variableScope", Message::never, "The scope of the variable %1 can be limited", "varname"));
|
||||||
err.push_back(Message("ifAssignment", Message::style, "Assignment in if-condition"));
|
err.push_back(Message("ifAssignment", Message::style, "Assignment in if-condition"));
|
||||||
|
err.push_back(Message("conditionAlwaysTrueFalse", Message::style, "Condition is always %1", "truefalse"));
|
||||||
|
|
||||||
// Generate code..
|
// Generate code..
|
||||||
std::cout << "Generate code.." << std::endl;
|
std::cout << "Generate code.." << std::endl;
|
||||||
|
|
Loading…
Reference in New Issue