Enhancements related to duplicate expression checking:

- Fixed astIsFloat() for complex expressions
- Enhanced support for commutative operators (#5260)
This commit is contained in:
PKEuS 2014-05-22 21:46:48 +02:00
parent f7a41057ad
commit bc0682d1e9
2 changed files with 39 additions and 5 deletions

View File

@ -51,6 +51,9 @@ static bool astIsFloat(const Token *tok, bool unknown)
return Token::findmatch(tok->variable()->typeStartToken(), "float|double", tok->variable()->typeEndToken()->next(), 0) != nullptr; return Token::findmatch(tok->variable()->typeStartToken(), "float|double", tok->variable()->typeEndToken()->next(), 0) != nullptr;
} }
if (tok->isOp())
return false;
return unknown; return unknown;
} }
@ -133,11 +136,21 @@ bool isSameExpression(const Token *tok1, const Token *tok2, const std::set<std::
// bailout when we see ({..}) // bailout when we see ({..})
if (tok1->str() == "{") if (tok1->str() == "{")
return false; return false;
if (!isSameExpression(tok1->astOperand1(), tok2->astOperand1(), constFunctions)) bool noncommuative_equals =
return false; isSameExpression(tok1->astOperand1(), tok2->astOperand1(), constFunctions);
if (!isSameExpression(tok1->astOperand2(), tok2->astOperand2(), constFunctions)) noncommuative_equals = noncommuative_equals &&
return false; isSameExpression(tok1->astOperand2(), tok2->astOperand2(), constFunctions);
if (noncommuative_equals)
return true; return true;
bool commutative = tok1->astOperand1() && tok1->astOperand2() && Token::Match(tok1, "+|*|%or%|%oror%|&|&&|^|==|!=");
bool commuative_equals = commutative &&
isSameExpression(tok1->astOperand2(), tok2->astOperand1(), constFunctions);
commuative_equals = commuative_equals &&
isSameExpression(tok1->astOperand1(), tok2->astOperand2(), constFunctions);
return commuative_equals;
} }
static bool isOppositeCond(const Token * const cond1, const Token * const cond2, const std::set<std::string> &constFunctions) static bool isOppositeCond(const Token * const cond1, const Token * const cond2, const std::set<std::string> &constFunctions)

View File

@ -4817,6 +4817,11 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Same expression on both sides of '&'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Same expression on both sides of '&'.\n", errout.str());
check("void foo(int a, int b) {\n"
" if ((a | b) == (a | b)) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Same expression on both sides of '=='.\n", errout.str());
check("void foo() {\n" check("void foo() {\n"
" if (a1[a2[c & 0xff] & 0xff]) {}\n" " if (a1[a2[c & 0xff] & 0xff]) {}\n"
"}"); "}");
@ -4892,6 +4897,22 @@ private:
" bool b = bar.isSet() && bar.isSet();\n" " bool b = bar.isSet() && bar.isSet();\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (style) Same expression on both sides of '&&'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (style) Same expression on both sides of '&&'.\n", errout.str());
check("void foo() {\n"
" if ((b + a) | (a + b)) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Same expression on both sides of '|'.\n", errout.str());
check("void foo() {\n"
" if ((b > a) | (a > b)) {}\n" // > is not commutative
"}");
ASSERT_EQUALS("", errout.str());
check("void foo() {\n"
" if ((b + a) > (a + b)) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Same expression on both sides of '>'.\n", errout.str());
} }
void duplicateExpression2() { // check if float is NaN or Inf void duplicateExpression2() { // check if float is NaN or Inf