diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7a0a2e4f5c9..1b342a55a88 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10020,6 +10020,15 @@ void Tokenizer::simplifyKeyword() } } + if (isC() && (tok->str() == "_Noreturn" || tok->str() == "noreturn")) { + Token *nameTok = tok; + while (Token::Match(nameTok, "%name%|*")) + nameTok = nameTok->next(); + if (nameTok && nameTok->str() == "(" && TokenList::isFunctionHead(nameTok, "{;")) { + nameTok->previous()->isAttributeNoreturn(true); + } + } + if (isC() || mSettings.standards.cpp == Standards::CPP03) { if (tok->str() == "auto") tok->deleteThis(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index f6923e7b83b..7d3146a2c78 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -154,6 +154,8 @@ class TestTokenizer : public TestFixture { TEST_CASE(simplifyExternC); TEST_CASE(simplifyKeyword); // #5842 - remove C99 static keyword between [] + TEST_CASE(simplifyKeywordNoreturn1); + TEST_CASE(simplifyKeywordNoreturn2); TEST_CASE(isOneNumber); @@ -3094,6 +3096,32 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("class Fred { } ;", tokenizeAndStringify("class DLLEXPORT Fred final { };\n")); } + void simplifyKeywordNoreturn1() { + const char code[] = "_Noreturn void f(void) {}\n"; + const char expected[] = "_Noreturn void f ( ) { }"; + SimpleTokenizer tokenizer(*this, false); + ASSERT(tokenizer.tokenize(code)); + + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + + const Token *f = Token::findsimplematch(tokenizer.tokens(), "f"); + ASSERT(f); + ASSERT(f->isAttributeNoreturn()); + } + + void simplifyKeywordNoreturn2() { + const char code[] = "noreturn void f(void) {}\n"; + const char expected[] = "noreturn void f ( ) { }"; + SimpleTokenizer tokenizer(*this, false); + ASSERT(tokenizer.tokenize(code)); + + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + + const Token *f = Token::findsimplematch(tokenizer.tokens(), "f"); + ASSERT(f); + ASSERT(f->isAttributeNoreturn()); + } + void implicitIntConst() { ASSERT_EQUALS("const int x ;", tokenizeAndStringify("const x;\n", dinit(TokenizeOptions, $.cpp = false))); ASSERT_EQUALS("const int * x ;", tokenizeAndStringify("const *x;\n", dinit(TokenizeOptions, $.cpp = false)));