Files
llvm-tms34010/clang/test/Parser/lambda-misplaced-capture-default.cpp
Oleksandr T. bb6d2bea64 [Clang] fix confusing diagnostics for lambdas with init-captures inside braced initializers (#166180)
Fixes #163498

---

This PR addresses the issue of confusing diagnostics for lambdas with
init-captures appearing inside braced initializers.

Cases such as:

```cpp
S s{[a(42), &] {}};
```

were misparsed as C99 array designators, producing unrelated
diagnostics, such as `use of undeclared identifier 'a'`, and `expected
']'`

---


https://github.com/llvm/llvm-project/blob/bb9bd5f263226840194b28457ddf9861986db51f/clang/lib/Parse/ParseInit.cpp#L470


https://github.com/llvm/llvm-project/blob/bb9bd5f263226840194b28457ddf9861986db51f/clang/lib/Parse/ParseInit.cpp#L74


https://github.com/llvm/llvm-project/blob/bb9bd5f263226840194b28457ddf9861986db51f/clang/include/clang/Parse/Parser.h#L4652-L4655


https://github.com/llvm/llvm-project/blob/24c22b7de620669aed9da28de323309c44a58244/clang/lib/Parse/ParseExprCXX.cpp#L871-L879

The tentative parser now returns `Incomplete` for partially valid lambda
introducers, preserving the `lambda` interpretation and allowing the
proper diagnostic to be issued later.

---

Clang now correctly recognizes such constructs as malformed lambda
introducers and emits the expected diagnostic — for example,
“capture-default must be first” — consistent with direct initialization
cases such as:

```cpp
S s([a(42), &] {});
```
2025-11-06 22:55:36 +02:00

48 lines
2.1 KiB
C++

// RUN: %clang_cc1 -std=c++20 -Wno-unused-value -fsyntax-only -verify %s
namespace misplaced_capture_default {
void Test() {
int i = 0;
[&, i, &] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
[&, i, = ] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
[=, &i, &] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
[=, &i, = ] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
[i, &] {}; // expected-error {{capture default must be first}}
[i, = ] {}; // expected-error {{capture default must be first}}
[i, = x] {}; // expected-error {{expected variable name or 'this' in lambda capture list}}
[=, &i] {}; // ok
[&, &i] {}; // expected-error {{'&' cannot precede a capture when the capture default is '&'}}
[&x = i] {}; // ok
[=, &x = i] {}; // ok
[x = &i] {}; // ok
[=, &x = &i] {}; // expected-error {{non-const lvalue reference to type 'int *' cannot bind to a temporary of type 'int *'}}
[&, this] {}; // expected-error {{'this' cannot be captured in this context}}
[i, &, x = 2] {}; // expected-error {{capture default must be first}}
[i, =, x = 2] {}; // expected-error {{capture default must be first}}
}
} // namespace misplaced_capture_default
namespace misplaced_capture_default_pack {
template <typename... Args> void Test(Args... args) {
[&, args...] {}; // ok
[args..., &] {}; // expected-error {{capture default must be first}}
[=, &args...] {}; // ok
[&, ... xs = &args] {}; // ok
[&, ... xs = &] {}; // expected-error {{expected expression}}
[... xs = &] {}; // expected-error {{expected expression}}
[... xs = &args, = ] {}; // expected-error {{capture default must be first}}
[... xs = &args, &] {}; // expected-error {{capture default must be first}}
}
} // namespace misplaced_capture_default_pack
namespace GH163498 {
struct S {
template <class T> S(T) {}
};
void t() {
S s{[a(42), &] {}}; // expected-error {{capture default must be first}}
}
}