Skip to content

Commit c2bd13e

Browse files
Fix #14181 FP nullPointerRedundantCheck / #14183 FP unusedFunction (#7873)
Co-authored-by: chrchr-github <noreply@github.com>
1 parent 2047c30 commit c2bd13e

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

lib/tokenize.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9411,6 +9411,8 @@ void Tokenizer::simplifyAttribute()
94119411

94129412
else if (Token::Match(attr, "[(,] unused|__unused__|used|__used__ [,)]")) {
94139413
Token *vartok = getVariableTokenAfterAttributes(tok);
9414+
if (!vartok)
9415+
vartok = functok;
94149416
if (vartok) {
94159417
const std::string &attribute(attr->strAt(1));
94169418
if (attribute.find("unused") != std::string::npos)
@@ -9526,7 +9528,7 @@ void Tokenizer::simplifyCPPAttribute()
95269528
head = skipCPPOrAlignAttribute(head)->next();
95279529
while (Token::Match(head, "%name%|::|*|&|<|>|,")) // skip return type
95289530
head = head->next();
9529-
if (head && head->str() == "(" && TokenList::isFunctionHead(head, "{;")) {
9531+
if (head && head->str() == "(" && (TokenList::isFunctionHead(head, "{;") || Token::simpleMatch(head->link(), ") __attribute__"))) {
95309532
head->previous()->isAttributeNoreturn(true);
95319533
}
95329534
} else if (Token::findsimplematch(tok->tokAt(2), "nodiscard", tok->link())) {

test/testtokenize.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ class TestTokenizer : public TestFixture {
272272
TEST_CASE(functionAttributeAfter2);
273273
TEST_CASE(functionAttributeListBefore);
274274
TEST_CASE(functionAttributeListAfter);
275-
275+
TEST_CASE(functionAttributeListAfter2);
276276
TEST_CASE(cppMaybeUnusedBefore);
277277
TEST_CASE(cppMaybeUnusedAfter);
278278
TEST_CASE(cppMaybeUnusedStructuredBinding);
@@ -4197,6 +4197,25 @@ class TestTokenizer : public TestFixture {
41974197
ASSERT(func8 && func8->isAttributeNoreturn() && func8->isAttributePure() && func8->isAttributeNothrow() && func8->isAttributeConst());
41984198
}
41994199

4200+
void functionAttributeListAfter2() {
4201+
const char code[] = "[[noreturn]] void func1(const char *format, ...) __attribute__((format(printf, 1, 2)));\n" // #14181
4202+
"void func2() __attribute__((unused));\n"; // #14183
4203+
const char expected[] = "void func1 ( const char * format , ... ) ; void func2 ( ) ;";
4204+
4205+
// tokenize..
4206+
SimpleTokenizer tokenizer(settings0, *this);
4207+
ASSERT(tokenizer.tokenize(code));
4208+
4209+
// Expected result..
4210+
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
4211+
4212+
const Token * func1 = Token::findsimplematch(tokenizer.tokens(), "func1");
4213+
const Token * func2 = Token::findsimplematch(tokenizer.tokens(), "func2");
4214+
4215+
ASSERT(func1 && func1->isAttributeNoreturn());
4216+
ASSERT(func2 && func2->isAttributeUnused());
4217+
}
4218+
42004219
void cppMaybeUnusedBefore() {
42014220
const char code[] = "[[maybe_unused]] int var {};";
42024221
const char expected[] = "int var { } ;";

0 commit comments

Comments
 (0)