From df1d6cf026f05677026e83e1519df280b62d8095 Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Wed, 22 Dec 2021 13:02:38 -0500 Subject: [PATCH] Fix the ability to recognize return types when simplifying attributes. (#3637) * Fix the ability to recognize return types when simplifying attributes. When parsing attributes to remove them, we have to allow for the case where the return type of the function that follows the attribute has a namespaced C++ type, like foo::bar . That means that :: has to be recognized as a valid token. Fix this in simplifyAttribute, and add tests for this as well. --- lib/tokenize.cpp | 8 +++++++- test/testsimplifytokens.cpp | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 4ef21f419..8bded705e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10974,8 +10974,14 @@ void Tokenizer::simplifyAttribute() Token *functok = nullptr; if (Token::Match(after, "%name%|*")) { Token *ftok = after; - while (Token::Match(ftok, "%name%|* !!(")) + while (Token::Match(ftok, "%name%|::|<|* !!(")) { + if (ftok->str() == "<") { + ftok = ftok->findClosingBracket(); + if (!ftok) + break; + } ftok = ftok->next(); + } if (Token::Match(ftok, "%name% (")) functok = ftok; } else if (Token::Match(after, "[;{=:]")) { diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 2a2d540ae..245ee2522 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -241,6 +241,9 @@ private: // remove calling convention __cdecl, __stdcall, ... TEST_CASE(simplifyCallingConvention); + // remove __attribute, __attribute__ + TEST_CASE(simplifyAttribute); + TEST_CASE(simplifyFunctorCall); TEST_CASE(simplifyFunctionPointer); // ticket #5339 (simplify function pointer after comma) @@ -4942,6 +4945,16 @@ private: ASSERT_EQUALS("enum E { CALLBACK } ;", tok("enum E { CALLBACK } ;", true, Settings::Unix32)); } + void simplifyAttribute() { + ASSERT_EQUALS("int f ( ) ;", tok("__attribute__ ((visibility(\"default\"))) int f();", true)); + ASSERT_EQUALS("int f ( ) ;", tok("__attribute__((visibility(\"default\"))) int f();", true)); + ASSERT_EQUALS("int f ( ) ;", tok("__attribute ((visibility(\"default\"))) int f();", true)); + ASSERT_EQUALS("int f ( ) ;", tok("__attribute__ ((visibility(\"default\"))) __attribute__ ((warn_unused_result)) int f();", true)); + ASSERT_EQUALS("blah :: blah f ( ) ;", tok("__attribute__ ((visibility(\"default\"))) blah::blah f();", true)); + ASSERT_EQUALS("template < T > Result < T > f ( ) ;", tok("template __attribute__ ((warn_unused_result)) Result f();", true)); + ASSERT_EQUALS("template < T , U > Result < T , U > f ( ) ;", tok("template __attribute__ ((warn_unused_result)) Result f();", true)); + } + void simplifyFunctorCall() { ASSERT_EQUALS("IncrementFunctor ( ) ( a ) ;", tok("IncrementFunctor()(a);", true)); }