diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 65c6066e8..326b19343 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -359,6 +359,19 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token (comp1 == ">" && comp2 == "<")))); } +bool isOppositeExpression(bool cpp, const Token * const tok1, const Token * const tok2, const Library& library, bool pure) +{ + if (!tok1 || !tok2) + return false; + if(isOppositeCond(true, cpp, tok1, tok2, library, pure)) + return true; + if(tok1->str() == "-") + return isSameExpression(cpp, true, tok1->astOperand1(), tok2, library, pure); + if(tok2->str() == "-") + return isSameExpression(cpp, true, tok2->astOperand1(), tok1, library, pure); + return false; +} + bool isConstExpression(const Token *tok, const Library& library, bool pure) { if (!tok) diff --git a/lib/astutils.h b/lib/astutils.h index 912c05587..4e05c9b53 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -71,6 +71,8 @@ bool isDifferentKnownValues(const Token * const tok1, const Token * const tok2); */ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token * const cond2, const Library& library, bool pure); +bool isOppositeExpression(bool cpp, const Token * const tok1, const Token * const tok2, const Library& library, bool pure); + bool isConstExpression(const Token *tok, const Library& library, bool pure); bool isWithoutSideEffects(bool cpp, const Token* tok); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6dcf17bb5..08b39c485 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1974,8 +1974,8 @@ void CheckOther::checkDuplicateExpression() } } } else if (styleEnabled && - isOppositeCond(true, _tokenizer->isCPP(), tok->astOperand1(), tok->astOperand2(), _settings->library, false) && - !Token::simpleMatch(tok, "=") && + isOppositeExpression(_tokenizer->isCPP(), tok->astOperand1(), tok->astOperand2(), _settings->library, false) && + !Token::Match(tok, "=|-|-=|/|/=") && isWithoutSideEffects(_tokenizer->isCPP(), tok->astOperand1())) { oppositeExpressionError(tok, tok, tok->str()); } else if (!Token::Match(tok, "[-/%]")) { // These operators are not associative diff --git a/test/testother.cpp b/test/testother.cpp index e9de3ea36..949bb5477 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3946,6 +3946,15 @@ private: check("void f(bool a) { a = !a; }"); ASSERT_EQUALS("", errout.str()); + + check("void f(int a) { if( a < -a ) {}}"); + ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (style) Opposite expression on both sides of '<'.\n", errout.str()); + + check("void f(int a) { a -= -a; }"); + ASSERT_EQUALS("", errout.str()); + + check("void f(int a) { a = a / (-a); }"); + ASSERT_EQUALS("", errout.str()); } void duplicateVarExpression() {