From 4257f9d46a34904c8072da611baab8fd6e82e8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 10 May 2022 20:59:24 +0200 Subject: [PATCH] Tokenizer: fix for __attribute__ before function that returns a reference --- lib/tokenize.cpp | 4 ++-- test/testtokenize.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 165b6c4b7..f0cd14080 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10983,9 +10983,9 @@ void Tokenizer::simplifyAttribute() syntaxError(tok); Token *functok = nullptr; - if (Token::Match(after, "%name%|*|(")) { + 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) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index be3efda9a..099ec4f8d 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -264,6 +264,7 @@ private: TEST_CASE(functionAttributeBefore1); TEST_CASE(functionAttributeBefore2); TEST_CASE(functionAttributeBefore3); + TEST_CASE(functionAttributeBefore4); TEST_CASE(functionAttributeAfter1); TEST_CASE(functionAttributeAfter2); TEST_CASE(functionAttributeListBefore); @@ -3678,6 +3679,22 @@ private: ASSERT(func_notret && func_notret->isAttributeNoreturn()); } + void functionAttributeBefore4() { + const char code[] = "__attribute__((const)) int& foo();"; + const char expected[] = "int & foo ( ) ;"; + + errout.str(""); + + // tokenize.. + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + + const Token* foo = Token::findsimplematch(tokenizer.tokens(), "foo"); + ASSERT(foo && foo->isAttributeConst()); + } + void functionAttributeAfter1() { const char code[] = "void func1() __attribute__((pure)) __attribute__((nothrow)) __attribute__((const));\n" "void func2() __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__));\n"