diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 40405c88f..cdcbf2c0d 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2526,24 +2526,30 @@ void CheckOther::checkSignOfUnsignedVariable() // check all the code in the function for (const Token *tok = scope->classStart; tok && tok != scope->classStart->link(); tok = tok->next()) { - if (Token::Match(tok, "( %var% <|<= 0 )") && tok->next()->varId()) + if (Token::Match(tok, "(|&&|%oror% %var% <|<= 0 )|&&|%oror%") && tok->next()->varId()) { const Variable * var = symbolDatabase->getVariableFromVarId(tok->next()->varId()); if (var && var->typeEndToken()->isUnsigned()) unsignedLessThanZeroError(tok->next(), tok->next()->str()); } - else if (Token::Match(tok, "( 0 > %var% )") && tok->tokAt(3)->varId()) + else if (Token::Match(tok, "(|&&|%oror% 0 > %var% )|&&|%oror%") && tok->tokAt(3)->varId()) { const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId()); if (var && var->typeEndToken()->isUnsigned()) unsignedLessThanZeroError(tok->tokAt(3), tok->strAt(3)); } - else if (Token::Match(tok, "( 0 <= %var% )") && tok->tokAt(3)->varId()) + else if (Token::Match(tok, "(|&&|%oror% 0 <= %var% )|&&|%oror%") && tok->tokAt(3)->varId()) { const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId()); if (var && var->typeEndToken()->isUnsigned()) unsignedPositiveError(tok->tokAt(3), tok->strAt(3)); } + else if (Token::Match(tok, "(|&&|%oror% %var% >= 0 )|&&|%oror%") && tok->next()->varId()) + { + const Variable * var = symbolDatabase->getVariableFromVarId(tok->next()->varId()); + if (var && var->typeEndToken()->isUnsigned()) + unsignedPositiveError(tok->next(), tok->next()->str()); + } } } } diff --git a/test/testother.cpp b/test/testother.cpp index 9d3569ca4..237ef2a6b 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3241,6 +3241,153 @@ private: " return false;\n" "}"); ASSERT_EQUALS("", errout.str()); + + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (x < 0 && y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is less than zero.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (x < 0 && y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (0 > x && y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is less than zero.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (0 > x && y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (x >= 0 && y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is positive is always true.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (x >= 0 && y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (y && x < 0)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is less than zero.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (y && x < 0)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (y && 0 > x)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is less than zero.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (y && 0 > x)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (y && x >= 0)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is positive is always true.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (y && x >= 0)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (x < 0 || y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is less than zero.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (x < 0 || y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (0 > x || y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is less than zero.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (0 > x || y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(unsigned int x, bool y) {\n" + " if (x >= 0 || y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned variable 'x' is positive is always true.\n", errout.str()); + + check_signOfUnsignedVariable( + "bool foo(int x, bool y) {\n" + " if (x >= 0 || y)" + " return true;\n" + " return false;\n" + "}"); + ASSERT_EQUALS("", errout.str()); } };