From 84ed7be5f2aa4a4fb6a4186fae197c17cd2e1291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 12 Sep 2025 10:46:35 +0200 Subject: [PATCH 1/2] add test --- test/testunusedvar.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index ac97629d112..0d7e4b00ae2 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -72,6 +72,7 @@ class TestUnusedVar : public TestFixture { TEST_CASE(structmember27); // #13367 TEST_CASE(structmember28); TEST_CASE(structmember29); // #14075 + TEST_CASE(structmember30); // #14131 TEST_CASE(structmember_macro); TEST_CASE(structmember_template_argument); // #13887 - do not report that member used in template argument is unused TEST_CASE(classmember); @@ -2023,6 +2024,17 @@ class TestUnusedVar : public TestFixture { ASSERT_EQUALS("[test.cpp:4:56]: (style) struct member 'S::storage' is never used. [unusedStructMember]\n", errout_str()); } + void structmember30() { // #14131 + checkStructMemberUsage("struct S\n" + "{\n" + "private:\n" + " __attribute__((unused)) int i1{};\n" + " int __attribute__((unused)) i2{}; // no warning\n" + " int i3 __attribute__((unused)) {};\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + void structmember_macro() { checkStructMemberUsageP("#define S(n) struct n { int a, b, c; };\n" "S(unused);\n"); From 5f1fa16c97c7a7f0b5e74d438efb417317d6865a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Fri, 12 Sep 2025 10:40:58 +0200 Subject: [PATCH 2/2] fix #14131 --- lib/tokenize.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index bd7c14c2c2d..b1bcdc27246 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9295,7 +9295,7 @@ static Token* getVariableTokenAfterAttributes(Token* tok) { Token *after = getTokenAfterAttributes(tok, true); // check if after variable name - if (Token::Match(after, ";|=")) { + if (Token::Match(after, "[;={]")) { Token *prev = tok->previous(); while (Token::simpleMatch(prev, "]")) prev = prev->link()->previous(); @@ -9303,9 +9303,16 @@ static Token* getVariableTokenAfterAttributes(Token* tok) { vartok = prev; } + // check if before variable name - else if (Token::Match(after, "%type%")) - vartok = after; + else { + while (Token::Match(after->next(), "const|volatile|static|*|&|&&|%type%")) { + after = after->next(); + } + if (Token::Match(after, "%name%")) { + vartok = after; + } + } return vartok; }