From 30cec97cc890d28b39520c906150a66ccb7a3a93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 12 Feb 2022 12:19:08 +0100 Subject: [PATCH] Tokenizer: Support C++20 default bit-field member initializer --- lib/tokenize.cpp | 10 ++++++---- test/testtokenize.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f13917896..f8f28e70e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10290,8 +10290,10 @@ void Tokenizer::findGarbageCode() const unknownMacroError(tok); // Assign/increment/decrement literal - else if (Token::Match(tok, "!!) %num%|%str%|%char% %assign%|++|--")) - syntaxError(tok, tok->next()->str() + " " + tok->strAt(2)); + else if (Token::Match(tok, "!!) %num%|%str%|%char% %assign%|++|--")) { + if (!isCPP() || mSettings->standards.cpp < Standards::CPP20 || !Token::Match(tok->previous(), "%name% : %num% =")) + syntaxError(tok, tok->next()->str() + " " + tok->strAt(2)); + } if (tok->isControlFlowKeyword() && Token::Match(tok, "if|while|for|switch")) { // if|while|for|switch (EXPR) { ... } if (tok->previous() && !Token::Match(tok->previous(), "%name%|:|;|{|}|)")) { @@ -11566,12 +11568,12 @@ void Tokenizer::simplifyBitfields() !Token::Match(tok->next(), "case|public|protected|private|class|struct") && !Token::simpleMatch(tok->tokAt(2), "default :")) { Token *tok1 = (tok->next()->str() == "const") ? tok->tokAt(3) : tok->tokAt(2); - if (Token::Match(tok1, "%name% : %num% ;")) + if (Token::Match(tok1, "%name% : %num% [;=]")) tok1->setBits(MathLib::toLongNumber(tok1->strAt(2))); if (tok1 && tok1->tokAt(2) && (Token::Match(tok1->tokAt(2), "%bool%|%num%") || !Token::Match(tok1->tokAt(2), "public|protected|private| %type% ::|<|,|{|;"))) { - while (tok1->next() && !Token::Match(tok1->next(), "[;,)]{}]")) { + while (tok1->next() && !Token::Match(tok1->next(), "[;,)]{}=]")) { if (Token::Match(tok1->next(), "[([]")) Token::eraseTokens(tok1, tok1->next()->link()); tok1->deleteNext(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index d5d8aa1b9..ea6400a43 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -448,6 +448,8 @@ private: TEST_CASE(simplifyIfSwitchForInit3); TEST_CASE(simplifyIfSwitchForInit4); TEST_CASE(simplifyIfSwitchForInit5); + + TEST_CASE(cpp20_default_bitfield_initializer); } #define tokenizeAndStringify(...) tokenizeAndStringify_(__FILE__, __LINE__, __VA_ARGS__) @@ -7213,6 +7215,15 @@ private: const char code[] = "void f() { if ([] { ; }) {} }"; ASSERT_EQUALS("void f ( ) { if ( [ ] { ; } ) { } }", tokenizeAndStringify(code, settings)); } + + void cpp20_default_bitfield_initializer() { + Settings settings; + const char code[] = "struct S { int a:2 = 0; };"; + settings.standards.cpp = Standards::CPP20; + ASSERT_EQUALS("struct S { int a ; a = 0 ; } ;", tokenizeAndStringify(code, settings)); + settings.standards.cpp = Standards::CPP17; + ASSERT_THROW(tokenizeAndStringify(code, settings), InternalError); + } }; REGISTER_TEST(TestTokenizer)