From d215a985384167f5bd34988600028608d3556fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 10 Sep 2025 11:02:35 +0200 Subject: [PATCH 1/5] update test --- test/cli/other_test.py | 64 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/test/cli/other_test.py b/test/cli/other_test.py index a747493e48d..a3b61ab355b 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -3164,6 +3164,70 @@ def test_check_unused_templates_func(tmp_path): # #13714 (void)(*((int*)0)); } +class S { +public: + template + void f_t_3() + { + (void)(*((int*)0)); + } +} + +template +static inline void f_t_4() +{ + (void)(*((int*)0)); +} + +template +const void *f_t_5() +{ + (void)(*((int*)0)); +} + +template +void f_t_6() __attribute__((noreturn)) +{ + (void)(*((int*)0)); +} + +template +__attribute__((noreturn)) void f_t_7() +{ + (void)(*((int*)0)); +} + +template +__declspec(noreturn) void f_t_8() +{ + (void)(*((int*)0)); +} + +template +[[noreturn]] void f_t_9() +{ + (void)(*((int*)0)); +} + +template +void f_t_10() noexcept(true) +{ + (void)(*((int*)0)); +} + +template +void f_t_11() throw(true) +{ + (void)(*((int*)0)); +} + +struct S { + template + void f_t_12() const { + (void)(*((int*)0)); + } +}; + void f() {} """) From 31efa3e99fae567da4bcfd84840902d66cae3c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 8 Sep 2025 11:24:10 +0200 Subject: [PATCH 2/5] fix #14118 --- lib/tokenize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 166662622a3..0db807333c0 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6363,7 +6363,7 @@ void Tokenizer::simplifyHeadersAndUnusedTemplates() } } - if (!tok->previous() || Token::Match(tok->previous(), "[;{}]")) { + if (!tok->previous() || Token::Match(tok->previous(), "[;{}:]")) { // Remove unused function declarations if (isIncluded && removeUnusedIncludedFunctions) { while (true) { From 2ff45b338f6d18c2efd170e169b9bd1a4784f5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Mon, 8 Sep 2025 13:10:58 +0200 Subject: [PATCH 3/5] fix #14117 --- lib/tokenize.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 0db807333c0..8e9e020d105 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6396,7 +6396,7 @@ void Tokenizer::simplifyHeadersAndUnusedTemplates() if (removeUnusedTemplates || (isIncluded && removeUnusedIncludedTemplates)) { if (Token::Match(tok, "template < %name%")) { - const Token *closingBracket = tok->next()->findClosingBracket(); + Token *closingBracket = tok->next()->findClosingBracket(); if (Token::Match(closingBracket, "> class|struct %name% [;:{]") && keep.find(closingBracket->strAt(2)) == keep.end()) { const Token *endToken = closingBracket->tokAt(3); if (endToken->str() == ":") { @@ -6410,11 +6410,68 @@ void Tokenizer::simplifyHeadersAndUnusedTemplates() Token::eraseTokens(tok, endToken); tok->deleteThis(); } - } else if (Token::Match(closingBracket, "> %type% %name% (") && Token::simpleMatch(closingBracket->linkAt(3), ") {") && keep.find(closingBracket->strAt(2)) == keep.end()) { - const Token *endToken = closingBracket->linkAt(3)->linkAt(1)->next(); - Token::eraseTokens(tok, endToken); - tok->deleteThis(); - goBack = true; + } else { + Token *funcTok = closingBracket->next(); + while (funcTok) { + if (Token::Match(funcTok, "__declspec|__attribute__ (")) { + funcTok = funcTok->linkAt(1); + if (funcTok) { + funcTok = funcTok->next(); + } + continue; + } + if (Token::Match(funcTok, "[ [")) { + funcTok = funcTok->link(); + if (funcTok) { + funcTok = funcTok->next(); + } + continue; + } + if (Token::Match(funcTok, "static|inline|const|%type%|&|&&|*") && !Token::Match(funcTok, "%name% (")) { + funcTok = funcTok->next(); + continue; + } + break; + } + if (!Token::Match(funcTok, "%name% (")) { + tok = funcTok; + continue; + } + funcTok = funcTok->linkAt(1); + if (funcTok) { + funcTok = funcTok->next(); + } + while (funcTok) { + if (Token::Match(funcTok, "__declspec|__attribute__|throw|noexcept (")) { + funcTok = funcTok->linkAt(1); + if (funcTok) { + funcTok = funcTok->next(); + } + continue; + } + if (Token::Match(funcTok, "[ [")) { + funcTok = funcTok->link(); + if (funcTok) { + funcTok = funcTok->next(); + } + continue; + } + if (Token::Match(funcTok, "const|volatile|&|&&")) { + funcTok = funcTok->next(); + continue; + } + break; + } + if (!Token::simpleMatch(funcTok, "{")) { + tok = funcTok; + continue; + } + funcTok = funcTok->link(); + if (funcTok) { + Token::eraseTokens(tok, funcTok->next()); + tok->deleteThis(); + goBack = true; + } } } } From b77d5866315337ffccc809ab82fd58e2d97300de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 10 Sep 2025 13:58:04 +0200 Subject: [PATCH 4/5] move invocation of simplifyHeadersAndUnusedTemplates --- lib/tokenize.cpp | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8e9e020d105..13f67a51eea 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5583,8 +5583,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) simplifyFunctionTryCatch(); - simplifyHeadersAndUnusedTemplates(); - // Remove __asm.. simplifyAsm(); @@ -5612,6 +5610,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) // remove __attribute__((?)) simplifyAttribute(); + simplifyHeadersAndUnusedTemplates(); + validate(); const SHOWTIME_MODES showTime = mTimerResults ? mSettings.showtime : SHOWTIME_MODES::SHOWTIME_NONE; @@ -6413,20 +6413,6 @@ void Tokenizer::simplifyHeadersAndUnusedTemplates() } else { Token *funcTok = closingBracket->next(); while (funcTok) { - if (Token::Match(funcTok, "__declspec|__attribute__ (")) { - funcTok = funcTok->linkAt(1); - if (funcTok) { - funcTok = funcTok->next(); - } - continue; - } - if (Token::Match(funcTok, "[ [")) { - funcTok = funcTok->link(); - if (funcTok) { - funcTok = funcTok->next(); - } - continue; - } if (Token::Match(funcTok, "static|inline|const|%type%|&|&&|*") && !Token::Match(funcTok, "%name% (")) { funcTok = funcTok->next(); continue; @@ -6442,20 +6428,13 @@ void Tokenizer::simplifyHeadersAndUnusedTemplates() funcTok = funcTok->next(); } while (funcTok) { - if (Token::Match(funcTok, "__declspec|__attribute__|throw|noexcept (")) { + if (Token::Match(funcTok, "throw|noexcept (")) { funcTok = funcTok->linkAt(1); if (funcTok) { funcTok = funcTok->next(); } continue; } - if (Token::Match(funcTok, "[ [")) { - funcTok = funcTok->link(); - if (funcTok) { - funcTok = funcTok->next(); - } - continue; - } if (Token::Match(funcTok, "const|volatile|&|&&")) { funcTok = funcTok->next(); continue; From 9cbe37f24aec72f8b2b3a1a8309f487a62e29f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 10 Sep 2025 13:58:30 +0200 Subject: [PATCH 5/5] handle constexpr --- lib/tokenize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 13f67a51eea..88316907b99 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6413,7 +6413,7 @@ void Tokenizer::simplifyHeadersAndUnusedTemplates() } else { Token *funcTok = closingBracket->next(); while (funcTok) { - if (Token::Match(funcTok, "static|inline|const|%type%|&|&&|*") && !Token::Match(funcTok, "%name% (")) { + if (Token::Match(funcTok, "constexpr|static|inline|const|%type%|&|&&|*") && !Token::Match(funcTok, "%name% (")) { funcTok = funcTok->next(); continue; }