Skip to content

Fix #15084 Wrong varid for lambda in constructor initializer list - #8917

Open
autoantwort wants to merge 1 commit into
cppcheck-opensource:mainfrom
autoantwort:fix-varid-initlist-lambda
Open

autoantwort wants to merge 1 commit into
cppcheck-opensource:mainfrom
autoantwort:fix-varid-initlist-lambda

Conversation

@autoantwort

Copy link
Copy Markdown
Contributor

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

In setVarIdPass1() the body of a lambda in a constructor initializer list was taken as the start of the constructor body, so the following members got the parameter's varid, lambda parameters leaked into the rest of the initializer list and the parameter varid leaked into later functions (FP uninitMemberVar, selfInitialization, functionStatic, unusedStructMember, constParameterPointer):

struct S {
    int* p;
    int x;
    S(int* p) : x([p] { return *p; }()), p(p) {}
};
struct T { int* p; int g(); };
int T::g() { return *p; }

A lambda in an initializer list (detected with findLambdaEndScope()) is now parsed like a lambda in executable code in its own scope, and the initializer list continues after it. Array sizes of new expressions (new T[n]{...}, new T*[n]{...}) are not taken as lambda captures.

findTypeEnd() now also skips template brackets that are not linked yet (they are linked in createLinks2() after setVarId()), so findLambdaEndScope() also works for trailing return types like -> std::vector<int>.

Covered: plain lambdas, parameters (also shadowing a constructor parameter), mutable, noexcept, trailing return types, [&]/[=], nested lambdas, braced member initializers. Template lambdas ([]<class T>(T v) {...}) are not handled because findLambdaEndScope() does not support them.

Follow-up of the review of #8885.

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

🤖 Generated with Claude Code

The lambda body in an initializer list was taken as the start of the
constructor body, so following members got the parameter varid, lambda
parameters leaked into the rest of the initializer list and the parameter
varid leaked into later functions (FP uninitMemberVar, selfInitialization,
functionStatic, constParameterPointer).

The lambda is now parsed like a lambda in executable code. findTypeEnd() also
finds the end of unlinked template brackets so that findLambdaEndScope() works
for trailing return types like std::vector<int> before createLinks2().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant