diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 2830e26a8..beae82e8e 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -245,15 +245,23 @@ void CheckOther::checkIncorrectLogicOperator() // If both terms reference a common variable and are not AND'd with anything, this is an error if (logicTok && (logicTok->strAt(-1) != "&&")) { + // (var11 != var12) || (var21 != var22) + const int varId11 = term1Tok->varId(); + const int varId12 = term1Tok->tokAt(2)->varId(); + const int varId21 = term2Tok->varId(); + const int varId22 = term2Tok->tokAt(2)->varId(); + + // (var != const1) || (var != const2) if (Token::Match(term1Tok, "%var%") && - ((term1Tok->str() == term2Tok->str()) || - (term1Tok->str() == term2Tok->strAt(2)))) + varId11 != 0 && + (varId11 == varId21 || varId11 == varId22)) { incorrectLogicOperatorError(term1Tok); } + // (const1 != var) || (const2 != var) else if (Token::Match(term1Tok->tokAt(2), "%var%") && - ((term1Tok->strAt(2) == term2Tok->str()) || - (term1Tok->strAt(2) == term2Tok->strAt(2)))) + varId12 != 0 && + (varId12 == varId21 || varId12 == varId22)) { incorrectLogicOperatorError(term1Tok->tokAt(2)); } diff --git a/test/testother.cpp b/test/testother.cpp index fe097ebd3..3b544bb4e 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1384,68 +1384,100 @@ private: void incorrectLogicOperator() { - check("void f() {\n" + check("void f(int x) {\n" " if ((x != 1) || (x != 3))\n" " a++;\n" "}\n" ); ASSERT_EQUALS("[test.cpp:2]: (warning) Mutual exclusion over || always evaluates to true. Did you intend to use && instead?\n", errout.str()); - check("void f() {\n" + check("void f(int x) {\n" " if (x != 1 || x != 3)\n" " a++;\n" "}\n" ); ASSERT_EQUALS("[test.cpp:2]: (warning) Mutual exclusion over || always evaluates to true. Did you intend to use && instead?\n", errout.str()); - check("void f() {\n" + check("void f(int x) {\n" " if (1 != x || 3 != x)\n" " a++;\n" "}\n" ); ASSERT_EQUALS("[test.cpp:2]: (warning) Mutual exclusion over || always evaluates to true. Did you intend to use && instead?\n", errout.str()); - check("void f() {\n" + check("void f(int x, int y) {\n" " if (x != 1 || y != 1)\n" " a++;\n" "}\n" ); ASSERT_EQUALS("", errout.str()); - check("void f() {\n" + check("void f(int x, int y) {\n" " if ((y == 1) && (x != 1) || (x != 3))\n" " a++;\n" "}\n" ); ASSERT_EQUALS("", errout.str()); - check("void f() {\n" + check("void f(int x, int y) {\n" " if ((x != 1) || (x != 3) && (y == 1))\n" " a++;\n" "}\n" ); ASSERT_EQUALS("", errout.str()); - check("void f() {\n" + check("void f(int x) {\n" " if ((x != 1) && (x != 3))\n" " a++;\n" "}\n" ); ASSERT_EQUALS("", errout.str()); - check("void f() {\n" + check("void f(int x) {\n" " if ((x == 1) || (x == 3))\n" " a++;\n" "}\n" ); ASSERT_EQUALS("", errout.str()); - check("void f() {\n" + check("void f(int x, int y) {\n" " if ((x != 1) || (y != 3))\n" " a++;\n" "}\n" ); ASSERT_EQUALS("", errout.str()); + + check("void f(int x, int y) {\n" + " if ((x != hotdog) || (y != hotdog))\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x, int y) {\n" + " if ((x != 5) || (y != 5))\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + + check("void f(int x) {\n" + " const int ERR1 = 5;\n" + " const int ERR2 = 6;\n" + " if ((x != ERR1) || (x != ERR2))\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:4]: (warning) Mutual exclusion over || always evaluates to true. Did you intend to use && instead?\n", errout.str()); + + check("void f(int x, int y) {\n" + " const int ERR1 = 5;\n" + " if ((x != ERR1) || (y != ERR1))\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); } };