Skip to content

Fix #15204 FP unusedFunction with compound literal as first argument - #9015

Open
mptre wants to merge 1 commit into
cppcheck-opensource:mainfrom
mptre:unused-function
Open

mptre wants to merge 1 commit into
cppcheck-opensource:mainfrom
mptre:unused-function

Conversation

@mptre

@mptre mptre commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

The check meant to skip function declarations and definitions inspected the link of the token following the opening parenthesis, i.e. the first argument, rather than the parenthesis itself. A call such as f((struct S){0}) was therefore mistaken for a definition and the call was never recorded.

The check meant to skip function declarations and definitions inspected
the link of the token following the opening parenthesis, i.e. the first
argument, rather than the parenthesis itself. A call such as
f((struct S){0}) was therefore mistaken for a definition and the call
was never recorded.

@dmcppcheck dmcppcheck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review

I found no problems. The old code ran linkAt(1) on the token after (, so it checked the link of the first argument. The PR checks the parenthesis' own link instead, which fixes the false positive for f((struct S){0}). The template branch (f<T>(...)) still gives the same result: ftok->link()->next() is null-safe through simpleMatch. The new check now also skips non-template name(...) { sequences, which the old code missed by accident. That covers constructor definitions and unexpanded macros like FOREACH(x) {. On the inputs I tried, this changed no output. There are no earlier review comments to track.

Testing

  • I built cppcheck and testrunner in pr/, and cppcheck in base/.
  • ./testrunner TestUnusedFunctions: 0 failures. test/cli/unused_function_test.py: 14 passed.
  • I compared base and PR with cppcheck -q --enable=unusedFunction on scratch files:
    • C compound literals: as first argument, as second argument, in extra parentheses k(((struct S){2})), and with several arguments. Base reported f, g and k as unused. The PR reports nothing, which is correct.
    • C++ explicit template call with a compound literal: f<S>((S){0}). Base reported a false positive; the PR does not.
    • Unchanged output on both sides:
      • definitions of constructors, destructors, const members and ns::g()
      • constructor initializer lists
      • a function defined through a macro
      • unknown macros followed by a block, such as FOREACH(n) { helper(n); } and FOREACH_ITEM(loopfn(n)) {...}
      • real unused or staticFunction cases
  • I also started a base-vs-PR diff over cppcheck's own cli/, frontend/ and samples/, but it ran past the timeout and was killed. That comparison is not done.

Automated review of e319a92 by Claude. The pull request was built and tested locally.

@dmcppcheck

Copy link
Copy Markdown
Contributor

Test results for commit e319a92 (tools/test-my-pr.py, main compared to this PR):

Test: http://ec2-16-170-140-253.eu-north-1.compute.amazonaws.com/pr-9015/
packages: 100
Differing warnings: 0 (+0 -0)
Timing: +0.1% (http://ec2-16-170-140-253.eu-north-1.compute.amazonaws.com/pr-9015/2026-11-11_07-30-37-e319a92a5ced_timing.html)

Posted automatically by the cppcheck PR test runner. +N: warnings only with this PR, -N: warnings only with main. The AI review is written by Claude and can be wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants