diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 454106c42..4b6e506ea 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -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()) diff --git a/test/testother.cpp b/test/testother.cpp index 0f9083f7e..750840f90 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -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