diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index e77641f89e7..4776cbea38f 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1575,10 +1575,19 @@ void CheckConditionImpl::alwaysTrueFalse() continue; if (Token::simpleMatch(tok->astParent(), "return") && Token::Match(tok, ".|%var%")) continue; - if (Token::Match(tok, "%num%|%bool%|%char%")) - continue; - if (Token::Match(tok, "! %num%|%bool%|%char%")) - continue; + bool warnForNumber = false; + if (Token::Match(tok, "%num%|%bool%|%char%")) { + const bool isZeroOrOne = (tok->getKnownIntValue() >> 1) == 0; + warnForNumber = !isZeroOrOne && tok->tokType() == Token::eNumber && tok->astParent() == condition->astParent(); + if (!warnForNumber) + continue; + } + if (Token::Match(tok, "! %num%|%bool%|%char%")) { + const bool isZeroOrOne = tok->next()->hasKnownIntValue() && (tok->next()->getKnownIntValue() >> 1) == 0; + warnForNumber = !isZeroOrOne && tok->next()->tokType() == Token::eNumber && tok->astParent() == condition->astParent(); + if (!warnForNumber) + continue; + } if (Token::Match(tok, "%oror%|&&")) { bool bail = false; for (const Token* op : { tok->astOperand1(), tok->astOperand2() }) { @@ -1603,7 +1612,7 @@ void CheckConditionImpl::alwaysTrueFalse() true)) continue; - if (!pedantic && isConstVarExpression(tok, [](const Token* tok) { + if (!pedantic && !warnForNumber && isConstVarExpression(tok, [](const Token* tok) { return Token::Match(tok, "[|(|&|+|-|*|/|%|^|>>|<<") && !Token::simpleMatch(tok, "( )"); })) continue; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index da4ecae43b3..85efa6eab63 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4949,6 +4949,28 @@ class TestCondition : public TestFixture { " return x ? false : true;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" + " if (42) {}\n" + " if (42U) {}\n" + " if (42L) {}\n" + " if (42UL) {}\n" + " if (42LL) {}\n" + " if (042) {}\n" + " if (0x42) {}\n" + " if (0b101010) {}\n" + " if (!42) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:9]: (style) Condition '42' is always true [knownConditionTrueFalse]\n" + "[test.cpp:3:9]: (style) Condition '42U' is always true [knownConditionTrueFalse]\n" + "[test.cpp:4:9]: (style) Condition '42L' is always true [knownConditionTrueFalse]\n" + "[test.cpp:5:9]: (style) Condition '42UL' is always true [knownConditionTrueFalse]\n" + "[test.cpp:6:9]: (style) Condition '42LL' is always true [knownConditionTrueFalse]\n" + "[test.cpp:7:9]: (style) Condition '042' is always true [knownConditionTrueFalse]\n" + "[test.cpp:8:9]: (style) Condition '0x42' is always true [knownConditionTrueFalse]\n" + "[test.cpp:9:9]: (style) Condition '0b101010' is always true [knownConditionTrueFalse]\n" + "[test.cpp:10:9]: (style) Condition '!42' is always false [knownConditionTrueFalse]\n", + errout_str()); } void alwaysTrueSymbolic()