You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
structP { int a; int b; };
voidrepro() {
constauto [a, b] = P{1, 2};
(void)[&](constauto c) { return c - b; }(2);
}
Produces a failure with error message:
/home/pmoran/clang_testcase.cpp:13:41: error: reference to local binding 'b' declared in enclosing function 'main' (void)[&](const auto c) { return c - b; }(2); ^/home/pmoran/clang_testcase.cpp:13:45: note: in instantiation of function template specialization 'main()::(anonymous class)::operator()<int>' requested here (void)[&](const auto c) { return c - b; }(2); ^/home/pmoran/clang_testcase.cpp:12:18: note: 'b' declared here const auto [a, b] = P{1, 2}; ^
It is my understanding that the capturing structured bindings in lambdas may not have been standards conforming in earlier language versions, but that it is standards-conforming in C++20. Commit 127bf44 added support for capturing structured bindings in lambdas to fix #54300 and #52720. The error seems to persist here specifically because the lambda is a generic lambda. If you change the argument from const auto c to instead be the const int c that the lambda's call will resolve to, the error goes away.
I chased the source of the error as far as clang/lib/Sema/SemaExpr.cpp line 18831 where we see this comment:
// If we are instantiating a generic lambda call operator body,// we do not want to capture new variables. What was captured// during either a lambdas transformation or initial parsing// should be used.
If you capture b by reference explicitly by name rather than using a default capture like so:
(void)[&b](constauto c) { return c - b; }(2);
Then you instead get this warning:
/home/pmoran/clang_testcase.cpp:13:12: warning: lambda capture 'b' is not required to be captured for this use [-Wunused-lambda-capture] (void)[&b](const auto c) { return c - b; }(2); ^
So I think the issue resides in the detection of which values need to be captured by a lambda's body (even though here neither b's type nor its value depend on the type parameter of the generic operator()).
Platform: I have only tested on linux x86_64,. but I don't think it's platform-specific
Versions Affected: I believe all versions up to and including the HEAD I pulled earlier today (2022-09-19).
The text was updated successfully, but these errors were encountered:
Structured bindings were not properly marked odr-used
and therefore captured in generic lambddas.
Fixesllvm#57826
It is unclear to me if further simplification can be gained
through the allowance described in
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0588r1.html.
Either way, I think this makes support for P0588 completes,
but we probably want to add test for that in a separate PR.
(and I lack confidence I understand P0588 sufficiently to assert
the completeness of our cnformance).
Differential Revision: https://reviews.llvm.org/D137244
Uh oh!
There was an error while loading. Please reload this page.
Building the following in
--std=c++20
Produces a failure with error message:
It is my understanding that the capturing structured bindings in lambdas may not have been standards conforming in earlier language versions, but that it is standards-conforming in C++20. Commit 127bf44 added support for capturing structured bindings in lambdas to fix #54300 and #52720. The error seems to persist here specifically because the lambda is a generic lambda. If you change the argument from
const auto c
to instead be theconst int c
that the lambda's call will resolve to, the error goes away.I chased the source of the error as far as clang/lib/Sema/SemaExpr.cpp line 18831 where we see this comment:
If you capture
b
by reference explicitly by name rather than using a default capture like so:Then you instead get this warning:
So I think the issue resides in the detection of which values need to be captured by a lambda's body (even though here neither
b
's type nor its value depend on the type parameter of the genericoperator()
).Platform: I have only tested on linux x86_64,. but I don't think it's platform-specific
Versions Affected: I believe all versions up to and including the HEAD I pulled earlier today (2022-09-19).
The text was updated successfully, but these errors were encountered: