More conservative check for non-commutative operator+ in isSameExpression() (#7938)

This commit is contained in:
PKEuS 2017-03-15 19:15:05 +01:00
parent bcba27fbb9
commit 816106560a
2 changed files with 16 additions and 9 deletions

View File

@ -215,18 +215,20 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2
if (noncommutativeEquals)
return true;
// in c++, a+b might be different to b+a, depending on the type of a and b
if (cpp && tok1->str() == "+") {
const ValueType* vt1 = tok1->astOperand1()->valueType();
const ValueType* vt2 = tok1->astOperand1()->valueType();
if (!(vt1 && (vt1->type >= ValueType::VOID || vt1->pointer) && vt2 && (vt2->type >= ValueType::VOID || vt2->pointer)))
return false;
}
const bool commutative = tok1->astOperand1() && tok1->astOperand2() && Token::Match(tok1, "%or%|%oror%|+|*|&|&&|^|==|!=");
bool commutativeEquals = commutative &&
isSameExpression(cpp, macro, tok1->astOperand2(), tok2->astOperand1(), library, pure);
commutativeEquals = commutativeEquals &&
isSameExpression(cpp, macro, tok1->astOperand1(), tok2->astOperand2(), library, pure);
// in c++, "a"+b might be different to b+"a"
if (cpp && commutativeEquals && tok1->str() == "+" &&
(tok1->astOperand1()->tokType() == Token::eString || tok1->astOperand2()->tokType() == Token::eString)) {
const Token * const other = tok1->astOperand1()->tokType() != Token::eString ? tok1->astOperand1() : tok1->astOperand2();
return other && astIsIntegral(other,false);
}
return commutativeEquals;
}

View File

@ -3615,7 +3615,7 @@ private:
ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (style) Same expression on both sides of '&&'.\n", errout.str());
check("void foo() {\n"
check("void foo(int a, int b) {\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());
@ -3625,12 +3625,12 @@ private:
"}");
ASSERT_EQUALS("", errout.str());
check("void foo() {\n"
check("void foo(int a, int b) {\n"
" if ((b > a) | (a > b)) {}\n" // > is not commutative
"}");
ASSERT_EQUALS("", errout.str());
check("void foo() {\n"
check("void foo(double a, double b) {\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());
@ -3887,6 +3887,11 @@ private:
" x = y ? (signed char)c : (unsigned char)c;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("std::string stringMerge(std::string const& x, std::string const& y) {\n" // #7938
" return ((x > y) ? (y + x) : (x + y));\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void checkSignOfUnsignedVariable() {