diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 9a3dd7483..60dcc1e05 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1025,6 +1025,11 @@ static std::string conditionString(const Token * tok) return tok->expressionString(); } +static bool isIfConstexpr(const Token* tok) { + const Token* const top = tok->astTop(); + return top && Token::simpleMatch(top->astOperand1(), "if") && top->astOperand1()->isConstexpr(); +} + void CheckCondition::checkIncorrectLogicOperator() { const bool printStyle = mSettings->severity.isEnabled(Severity::style); @@ -1144,10 +1149,12 @@ void CheckCondition::checkIncorrectLogicOperator() ErrorPath errorPath; // Opposite comparisons around || or && => always true or always false - if (!isfloat && isOppositeCond(tok->str() == "||", mTokenizer->isCPP(), tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true, &errorPath)) { - - const bool alwaysTrue(tok->str() == "||"); - incorrectLogicOperatorError(tok, conditionString(tok), alwaysTrue, inconclusive, errorPath); + const bool isLogicalOr(tok->str() == "||"); + if (!isfloat && isOppositeCond(isLogicalOr, mTokenizer->isCPP(), tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true, &errorPath)) { + if (!isIfConstexpr(tok)) { + const bool alwaysTrue(isLogicalOr); + incorrectLogicOperatorError(tok, conditionString(tok), alwaysTrue, inconclusive, errorPath); + } continue; } @@ -1494,6 +1501,9 @@ void CheckCondition::alwaysTrueFalse() if (hasSizeof) continue; + if (isIfConstexpr(tok)) + continue; + alwaysTrueFalseError(tok, &tok->values().front()); } } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 4c5c28fad..a94a505dc 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -3438,6 +3438,15 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + // #9954 + check("void f() {\n" + " const size_t a(8 * sizeof(short));\n" + " const size_t b(8 * sizeof(int));\n" + " if constexpr (a == 16 && b == 16) {}\n" + " else if constexpr (a == 16 && b == 32) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + // #9319 check("struct S {\n" " int a;\n"