Improved astIsFloat(): Handle function calls and sizeof, fixed ordering of checks

Handle sizeof in isSameExpression() (#6851)
This commit is contained in:
PKEuS 2015-07-29 14:27:53 +02:00
parent 120f3072eb
commit 738057229c
2 changed files with 40 additions and 15 deletions

View File

@ -34,27 +34,37 @@ namespace {
bool astIsFloat(const Token *tok, bool unknown)
{
if (tok->astOperand2() && (tok->str() == "." || tok->str() == "::"))
return astIsFloat(tok->astOperand2(), unknown);
if (tok->astOperand1() && tok->str() != "?" && astIsFloat(tok->astOperand1(),unknown))
return true;
if (tok->astOperand2() && astIsFloat(tok->astOperand2(), unknown))
return true;
// TODO: handle arrays
if (tok->isNumber())
return MathLib::isFloat(tok->str());
if (tok->isName()) {
// TODO: check function calls, struct members, arrays, etc also
if (!tok->variable())
return unknown;
if (tok->variable())
return tok->variable()->isFloatingType();
return tok->variable()->isFloatingType();
return unknown;
}
if (tok->str() == "(") {
// cast
if (Token::Match(tok, "( const| float|double )"))
return true;
// Function call
if (tok->previous()->function())
return Token::Match(tok->previous()->function()->retDef, "float|double");
if (tok->strAt(-1) == "sizeof")
return false;
return unknown;
}
// cast
if (Token::Match(tok, "( const| float|double )"))
if (tok->astOperand2() && (tok->str() == "." || tok->str() == "::"))
return astIsFloat(tok->astOperand2(), unknown);
if (tok->astOperand1() && tok->str() != "?" && astIsFloat(tok->astOperand1(), unknown))
return true;
if (tok->astOperand2() && astIsFloat(tok->astOperand2(), unknown))
return true;
if (tok->isOp())
@ -105,7 +115,7 @@ bool isSameExpression(const Tokenizer *tokenizer, const Token *tok1, const Token
return false;
if (tok1->isExpandedMacro() || tok2->isExpandedMacro())
return false;
if (tok1->isName() && tok1->next()->str() == "(") {
if (tok1->isName() && tok1->next()->str() == "(" && tok1->str() != "sizeof") {
if (!tok1->function() && !Token::Match(tok1->previous(), ".|::") && constFunctions.find(tok1->str()) == constFunctions.end() && !tok1->isAttributeConst() && !tok1->isAttributePure())
return false;
else if (tok1->function() && !tok1->function()->isConst() && !tok1->function()->isAttributeConst() && !tok1->function()->isAttributePure())

View File

@ -4224,6 +4224,21 @@ private:
" static_assert(FourInEnumOne == FourInEnumTwo, "");\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void foo(int a, int b) {\n"
" if (sizeof(a) == sizeof(a)) { }\n"
" if (sizeof(a) == sizeof(b)) { }\n"
"}");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Same expression on both sides of '=='.\n", errout.str());
check("float bar(int) __attribute__((pure));\n"
"char foo(int) __attribute__((pure));\n"
"int test(int a, int b) {\n"
" if (bar(a) == bar(a)) { }\n"
" if (unknown(a) == unknown(a)) { }\n"
" if (foo(a) == foo(a)) { }\n"
"}");
ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:6]: (style) Same expression on both sides of '=='.\n", errout.str());
}
void duplicateExpression2() { // check if float is NaN or Inf