Skip to content

Fix #15079 FP syntaxError for C-style cast before scope operator - #8909

Open
autoantwort wants to merge 1 commit into
cppcheck-opensource:mainfrom
autoantwort:fix-garbage-cast-scope
Open

autoantwort wants to merge 1 commit into
cppcheck-opensource:mainfrom
autoantwort:fix-garbage-cast-scope

Conversation

@autoantwort

Copy link
Copy Markdown
Contributor

https://trac.cppcheck.net/ticket/15079

The check added in a294079 (#15060) reports every ) followed by :: unless the ( belongs to a control flow keyword or decltype. That also rejects valid code, and the whole file is skipped:

(void)::CloseHandle(h);
HBITMAP old = (HBITMAP)::SelectObject(dc, bmp);
new (p) ::N::T;

Now the error is only reported when the parenthesis follows a non-keyword name, the unknown macro case (CL_NS(util)::X, void C(abc)::f()) the check was added for.

On our code base this regression dropped the number of findings from 17401 to 9193 (10 files with casts like the ones above, one of them a widely included header). With this change the count is back to the previous level.

This PR was created by Claude Code (an AI coding agent) on behalf of @autoantwort.

🤖 Generated with Claude Code

The check added in a294079 (#15060) reports every `)` followed by `::`
unless the `(` belongs to a control flow keyword or decltype. That also
rejects valid code like `(HWND)::SendMessage(...)` or placement new
`new (p) ::N::T`, so whole translation units are skipped.

Only report when the parenthesis follows a non-keyword name, which is the
unknown macro case the check was added for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread lib/tokenize.cpp
const Token* const prev = tok->linkAt(-1)->tokAt(-1);
if (!Token::Match(prev, "%name% (") || (!prev->isControlFlowKeyword() && prev->str() != "decltype")) {
if (prev && prev->isUpperCaseName())
if (Token::Match(prev, "%name% (") && !prev->isKeyword()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is an AI review take it with a grain of salt. Please feel free to reject it by clicking on Resolve button

Whether a token is a keyword depends on --std (TokenList::isKeyword() uses Keywords::getAll(standards.cpp)). With --std=c++03, decltype is a plain name, so this now gives a false syntaxError:

$ cppcheck --std=c++03 dt.cpp
dt.cpp:3:12: error: syntax error [syntaxError]
decltype(s)::type i;

The old code avoided this with prev->str() != "decltype". Maybe keep that, e.g. && !prev->isKeyword() && prev->str() != "decltype".

Comment thread test/testtokenize.cpp
" *p = -*p;\n"
"}\n"));

ASSERT_NO_THROW(tokenizeAndStringify("void f(void* h) {\n" // cast before global scope operator

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is an AI review take it with a grain of salt. Please feel free to reject it by clicking on Resolve button

In this project tests usually reference the ticket number, e.g. // #15079.

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