From 965644ec984e07b850bcf510bc58ca81fd216a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Thu, 3 Sep 2026 09:38:35 +0200 Subject: [PATCH 1/5] test --- test/testtokenize.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index f6923e7b83b..69b4b328f2e 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -154,6 +154,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(simplifyExternC); TEST_CASE(simplifyKeyword); // #5842 - remove C99 static keyword between [] + TEST_CASE(simplifyKeywordNoreturn); TEST_CASE(isOneNumber); @@ -3094,6 +3095,19 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("class Fred { } ;", tokenizeAndStringify("class DLLEXPORT Fred final { };\n")); } + void simplifyKeywordNoreturn() { + const char code[] = "_Noreturn void f(void) {}\n"; + const char expected[] = "void f ( ) { }"; + SimpleTokenizer tokenizer(settings2 /* C11 */, *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))); From 38c49e02680b85c9cd780d84f76d519cc426a5da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 2 Sep 2026 15:36:07 +0200 Subject: [PATCH 2/5] fix --- lib/tokenize.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7a0a2e4f5c9..753ae7fb666 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10001,6 +10001,8 @@ void Tokenizer::simplifyKeyword() const bool c99 = isC() && mSettings.standards.c >= Standards::C99; const bool cpp11 = isCPP() && mSettings.standards.cpp >= Standards::CPP11; const bool cpp20 = isCPP() && mSettings.standards.cpp >= Standards::CPP20; + const bool have_Noreturn = isC() && mSettings.standards.c >= Standards::C11 + && mSettings.standards.c < Standards::C23; for (Token *tok = list.front(); tok; tok = tok->next()) { if (keywords.find(tok->str()) != keywords.end()) { @@ -10020,6 +10022,15 @@ void Tokenizer::simplifyKeyword() } } + if (have_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); + tok->deleteThis(); + } + if (isC() || mSettings.standards.cpp == Standards::CPP03) { if (tok->str() == "auto") tok->deleteThis(); From c890ab12bfb8c1d715c6890dce81e074d25f5a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 4 Sep 2026 08:46:17 +0200 Subject: [PATCH 3/5] no standard check --- lib/tokenize.cpp | 9 ++++----- test/testtokenize.cpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 753ae7fb666..f681daa52fd 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10001,8 +10001,6 @@ void Tokenizer::simplifyKeyword() const bool c99 = isC() && mSettings.standards.c >= Standards::C99; const bool cpp11 = isCPP() && mSettings.standards.cpp >= Standards::CPP11; const bool cpp20 = isCPP() && mSettings.standards.cpp >= Standards::CPP20; - const bool have_Noreturn = isC() && mSettings.standards.c >= Standards::C11 - && mSettings.standards.c < Standards::C23; for (Token *tok = list.front(); tok; tok = tok->next()) { if (keywords.find(tok->str()) != keywords.end()) { @@ -10022,13 +10020,14 @@ void Tokenizer::simplifyKeyword() } } - if (have_Noreturn && tok->str() == "_Noreturn") { + if (isC() && tok->str() == "_Noreturn") { Token *nameTok = tok; while (Token::Match(nameTok, "%name%|*")) nameTok = nameTok->next(); - if (nameTok && nameTok->str() == "(" && TokenList::isFunctionHead(nameTok, "{;")) + if (nameTok && nameTok->str() == "(" && TokenList::isFunctionHead(nameTok, "{;")) { nameTok->previous()->isAttributeNoreturn(true); - tok->deleteThis(); + tok->deleteThis(); + } } if (isC() || mSettings.standards.cpp == Standards::CPP03) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 69b4b328f2e..1166b630455 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -3098,7 +3098,7 @@ class TestTokenizer : public TestFixture { void simplifyKeywordNoreturn() { const char code[] = "_Noreturn void f(void) {}\n"; const char expected[] = "void f ( ) { }"; - SimpleTokenizer tokenizer(settings2 /* C11 */, *this, false); + SimpleTokenizer tokenizer(*this, false); ASSERT(tokenizer.tokenize(code)); ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); From a3ab3737490af3b3af35a82c5554007926f69c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 4 Sep 2026 09:07:27 +0200 Subject: [PATCH 4/5] also handle noreturn --- lib/tokenize.cpp | 2 +- test/testtokenize.cpp | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f681daa52fd..e95ac7a8f3c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10020,7 +10020,7 @@ void Tokenizer::simplifyKeyword() } } - if (isC() && tok->str() == "_Noreturn") { + if (isC() && (tok->str() == "_Noreturn" || tok->str() == "noreturn")) { Token *nameTok = tok; while (Token::Match(nameTok, "%name%|*")) nameTok = nameTok->next(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 1166b630455..8c87283a43b 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -154,7 +154,8 @@ class TestTokenizer : public TestFixture { TEST_CASE(simplifyExternC); TEST_CASE(simplifyKeyword); // #5842 - remove C99 static keyword between [] - TEST_CASE(simplifyKeywordNoreturn); + TEST_CASE(simplifyKeywordNoreturn1); + TEST_CASE(simplifyKeywordNoreturn2); TEST_CASE(isOneNumber); @@ -3095,7 +3096,7 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("class Fred { } ;", tokenizeAndStringify("class DLLEXPORT Fred final { };\n")); } - void simplifyKeywordNoreturn() { + void simplifyKeywordNoreturn1() { const char code[] = "_Noreturn void f(void) {}\n"; const char expected[] = "void f ( ) { }"; SimpleTokenizer tokenizer(*this, false); @@ -3108,6 +3109,19 @@ class TestTokenizer : public TestFixture { ASSERT(f->isAttributeNoreturn()); } + void simplifyKeywordNoreturn2() { + const char code[] = "noreturn void f(void) {}\n"; + const char expected[] = "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))); From cc82905824355dd413b0b22afa4a2be5f2cc4aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Tue, 8 Sep 2026 08:08:29 +0200 Subject: [PATCH 5/5] don't delete token, needed by misra.py --- lib/tokenize.cpp | 1 - test/testtokenize.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index e95ac7a8f3c..1b342a55a88 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10026,7 +10026,6 @@ void Tokenizer::simplifyKeyword() nameTok = nameTok->next(); if (nameTok && nameTok->str() == "(" && TokenList::isFunctionHead(nameTok, "{;")) { nameTok->previous()->isAttributeNoreturn(true); - tok->deleteThis(); } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 8c87283a43b..7d3146a2c78 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -3098,7 +3098,7 @@ class TestTokenizer : public TestFixture { void simplifyKeywordNoreturn1() { const char code[] = "_Noreturn void f(void) {}\n"; - const char expected[] = "void f ( ) { }"; + const char expected[] = "_Noreturn void f ( ) { }"; SimpleTokenizer tokenizer(*this, false); ASSERT(tokenizer.tokenize(code)); @@ -3111,7 +3111,7 @@ class TestTokenizer : public TestFixture { void simplifyKeywordNoreturn2() { const char code[] = "noreturn void f(void) {}\n"; - const char expected[] = "void f ( ) { }"; + const char expected[] = "noreturn void f ( ) { }"; SimpleTokenizer tokenizer(*this, false); ASSERT(tokenizer.tokenize(code));