Skip to content

Commit 2ebe4cc

Browse files
committed
Fix #11538: Fix syntax error on C++23 'if consteval' / 'if !consteval'
The tokenizer only recognized 'if constexpr (...)' and treated any other 'if <name>' without parentheses as a syntax error, so C++23's 'if consteval { ... }' and 'if !consteval { ... }' were rejected. Rewrite them to 'if ( __cppcheck_consteval__ ) { ... }' and 'if ( ! __cppcheck_consteval__ ) { ... }' respectively, using a synthetic unresolved symbol rather than a boolean literal so that valueflow can't treat the condition as always true/false.
1 parent 3deb36d commit 2ebe4cc

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

lib/tokenize.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5721,7 +5721,22 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
57215721

57225722
// if MACRO
57235723
for (Token *tok = list.front(); tok; tok = tok->next()) {
5724-
if (Token::Match(tok, "if|for|while %name% (")) {
5724+
if (Token::simpleMatch(tok, "if consteval {")) {
5725+
// 'if consteval { ... }' -> 'if ( __cppcheck_consteval__ ) { ... }'
5726+
Token *parTok = tok->next();
5727+
parTok->str("(");
5728+
Token *evalTok = parTok->insertToken("__cppcheck_consteval__");
5729+
evalTok->originalName("consteval");
5730+
evalTok->insertToken(")");
5731+
} else if (Token::simpleMatch(tok, "if ! consteval {")) {
5732+
// 'if !consteval { ... }' -> 'if ( ! __cppcheck_consteval__ ) { ... }'
5733+
Token *notTok = tok->next();
5734+
notTok->insertTokenBefore("(");
5735+
Token *evalTok = notTok->next();
5736+
evalTok->str("__cppcheck_consteval__");
5737+
evalTok->originalName("consteval");
5738+
evalTok->insertToken(")");
5739+
} else if (Token::Match(tok, "if|for|while %name% (")) {
57255740
if (Token::simpleMatch(tok, "for each")) {
57265741
// 'for each (x in y )' -> 'for (x : y)'
57275742
if (Token* in = Token::findsimplematch(tok->tokAt(2), "in", tok->linkAt(2)))

test/testtokenize.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class TestTokenizer : public TestFixture {
104104

105105
TEST_CASE(foreach); // #3690
106106
TEST_CASE(ifconstexpr);
107+
TEST_CASE(ifconsteval);
107108

108109
TEST_CASE(combineOperators);
109110

@@ -1042,6 +1043,18 @@ class TestTokenizer : public TestFixture {
10421043
filter_valueflow(errout_str()));
10431044
}
10441045

1046+
void ifconsteval() {
1047+
ASSERT_EQUALS("void f ( ) { if ( __cppcheck_consteval__ ) { bar ( ) ; } }", tokenizeAndStringify("void f() { if consteval { bar(); } }"));
1048+
filter_valueflow(errout_str());
1049+
1050+
ASSERT_EQUALS("void f ( ) { if ( ! __cppcheck_consteval__ ) { bar ( ) ; } }", tokenizeAndStringify("void f() { if !consteval { bar(); } }"));
1051+
filter_valueflow(errout_str());
1052+
1053+
ASSERT_EQUALS("void f ( ) { if ( __cppcheck_consteval__ ) { bar ( ) ; } else { baz ( ) ; } }",
1054+
tokenizeAndStringify("void f() { if consteval { bar(); } else { baz(); } }"));
1055+
filter_valueflow(errout_str());
1056+
}
1057+
10451058
void combineOperators() {
10461059
ASSERT_EQUALS("; private: ;", tokenizeAndStringify(";private:;"));
10471060
ASSERT_EQUALS("; protected: ;", tokenizeAndStringify(";protected:;"));

0 commit comments

Comments
 (0)