diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 2c9f84dca..fb66631e0 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1345,7 +1345,7 @@ void CheckCondition::alwaysTrueFalse() continue; const bool constIfWhileExpression = - tok->astParent() && Token::Match(tok->astTop()->astOperand1(), "if|while") && + tok->astParent() && Token::Match(tok->astTop()->astOperand1(), "if|while") && !tok->astTop()->astOperand1()->isConstexpr() && (Token::Match(tok->astParent(), "%oror%|&&") || Token::Match(tok->astParent()->astOperand1(), "if|while")); const bool constValExpr = tok->isNumber() && Token::Match(tok->astParent(),"%oror%|&&|?"); // just one number in boolean expression const bool compExpr = Token::Match(tok, "%comp%|!"); // a compare expression diff --git a/lib/token.h b/lib/token.h index 1d1a6e23e..27a6a17b3 100644 --- a/lib/token.h +++ b/lib/token.h @@ -566,6 +566,13 @@ public: setFlag(fIncompleteVar, b); } + bool isConstexpr() const { + return getFlag(fConstexpr); + } + void isConstexpr(bool b) { + setFlag(fConstexpr, b); + } + bool isBitfield() const { return mImpl->mBits > 0; @@ -1098,6 +1105,7 @@ private: fIsAttributeNodiscard = (1 << 23), // __attribute__ ((warn_unused_result)), [[nodiscard]] fAtAddress = (1 << 24), // @ 0x4000 fIncompleteVar = (1 << 25), + fConstexpr = (1 << 26), }; Token::Type mTokType; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index cc2dc4b40..80f162f55 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4233,6 +4233,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) tok->deleteNext(); } else if (tok->strAt(1) == "constexpr") { tok->deleteNext(); + tok->isConstexpr(true); } else { syntaxError(tok); } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 998159050..87d1f8e35 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -3197,7 +3197,7 @@ private: " }\n" "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (style) Condition 'array' is always true\n", errout.str()); - + check("void f(int *array, int size ) {\n" " for(int i = 0; i < size; ++i) {\n" " if(array == 0)\n" @@ -3206,6 +3206,16 @@ private: " }\n" "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (style) Condition 'array' is always true\n", errout.str()); + + // #9277 + check("int f() {\n" + " constexpr bool x = true;\n" + " if constexpr (x)\n" + " return 0;\n" + " else\n" + " return 1;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void multiConditionAlwaysTrue() {