From 107eea236f3db04f759471f89530c5eb497283bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 24 May 2023 10:33:53 +0200 Subject: [PATCH] Improved handling of alignas. alignas will not be removed from now on so we don't loose this information. (#5081) --- lib/symboldatabase.cpp | 3 +++ lib/tokenize.cpp | 19 +++++-------------- lib/tokenize.h | 3 --- test/testsymboldatabase.cpp | 10 ++++++++++ test/testvarid.cpp | 9 +++++++++ 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 5c34877e8..cc0acb6cb 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4761,6 +4761,9 @@ bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token* localTypeTok = skipScopeIdentifiers(tok); const Token* localVarTok = nullptr; + while (Token::simpleMatch(localTypeTok, "alignas (") && Token::Match(localTypeTok->linkAt(1), ") %name%")) + localTypeTok = localTypeTok->linkAt(1)->next(); + if (Token::Match(localTypeTok, "%type% <")) { if (Token::Match(tok, "const_cast|dynamic_cast|reinterpret_cast|static_cast <")) return false; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 0f28cc1fa..6094e8ed4 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4094,6 +4094,10 @@ static bool setVarIdParseDeclaration(Token** tok, const VariableMap& variableMap bool ref = false; while (tok2) { if (tok2->isName()) { + if (Token::simpleMatch(tok2, "alignas (")) { + tok2 = tok2->linkAt(1)->next(); + continue; + } if (cpp && Token::Match(tok2, "namespace|public|private|protected")) return false; if (cpp && Token::simpleMatch(tok2, "decltype (")) { @@ -5364,8 +5368,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) // Remove extra "template" tokens that are not used by cppcheck removeExtraTemplateKeywords(); - removeAlignas(); - simplifySpaceshipOperator(); // Bail out if code is garbage @@ -5402,7 +5404,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) // simplify namespace aliases simplifyNamespaceAliases(); - // Remove [[attribute]] and alignas(?) + // Remove [[attribute]] simplifyCPPAttribute(); // remove __attribute__((?)) @@ -8961,17 +8963,6 @@ void Tokenizer::simplifyCPPAttribute() } } -void Tokenizer::removeAlignas() -{ - if (!isCPP() || mSettings->standards.cpp < Standards::CPP11) - return; - - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "[;{}] alignas (") && Token::Match(tok->linkAt(2), ") %name%")) - Token::eraseTokens(tok, tok->linkAt(2)->next()); - } -} - void Tokenizer::simplifySpaceshipOperator() { if (isCPP() && mSettings->standards.cpp >= Standards::CPP20) { diff --git a/lib/tokenize.h b/lib/tokenize.h index 2ef2ac510..c6ab8dd03 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -475,9 +475,6 @@ private: */ void simplifyCppcheckAttribute(); - /** Remove alignas */ - void removeAlignas(); - /** Simplify c++20 spaceship operator */ void simplifySpaceshipOperator(); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 730f6c8b6..44b2d21f9 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -160,6 +160,7 @@ private: TEST_CASE(variableVolatile); TEST_CASE(variableConstexpr); TEST_CASE(isVariableDecltype); + TEST_CASE(isVariableAlignas); TEST_CASE(VariableValueType1); TEST_CASE(VariableValueType2); @@ -1475,6 +1476,15 @@ private: ASSERT_EQUALS("signed int *", c->valueType()->str()); } + void isVariableAlignas() { + GET_SYMBOL_DB_C("extern alignas(16) int x;\n" + "alignas(16) int x;\n"); + ASSERT(db); + ASSERT_EQUALS(2, db->scopeList.front().varlist.size()); + const Variable *x1 = Token::findsimplematch(tokenizer.tokens(), "x")->variable(); + ASSERT(x1 && Token::simpleMatch(x1->typeStartToken(), "alignas ( 16 ) int x ;")); + } + void memberVar1() { GET_SYMBOL_DB("struct Foo {\n" " int x;\n" diff --git a/test/testvarid.cpp b/test/testvarid.cpp index e908d1d6e..a08cf582b 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -187,6 +187,7 @@ private: TEST_CASE(varid_declInIfCondition); TEST_CASE(varid_globalScope); TEST_CASE(varid_function_pointer_args); + TEST_CASE(varid_alignas); TEST_CASE(varidclass1); TEST_CASE(varidclass2); @@ -3045,6 +3046,14 @@ private: ASSERT_EQUALS("1: void f ( void ( * g@1 ) ( int , IN int ) ) { }\n", tokenize(code3)); } + void varid_alignas() { + const char code[] = "extern alignas(16) int x;\n" + "alignas(16) int x;"; + const char expected[] = "1: extern alignas ( 16 ) int x@1 ;\n" + "2: alignas ( 16 ) int x@2 ;\n"; + ASSERT_EQUALS(expected, tokenize(code, "test.c")); + } + void varidclass1() { const std::string actual = tokenize( "class Fred\n"