mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 17:46:04 +00:00

This fixes some problems wrt dependence of captures in lambdas with an explicit object parameter. [temp.dep.expr] states that > An id-expression is type-dependent if [...] its terminal name is > - associated by name lookup with an entity captured by copy > ([expr.prim.lambda.capture]) in a lambda-expression that has > an explicit object parameter whose type is dependent [dcl.fct]. There were several issues with our implementation of this: 1. we were treating by-reference captures as dependent rather than by-value captures; 2. tree transform wasn't checking whether referring to such a by-value capture should make a DRE dependent; 3. when checking whether a DRE refers to such a by-value capture, we were only looking at the immediately enclosing lambda, and not at any parent lambdas; 4. we also forgot to check for implicit by-value captures; 5. lastly, we were attempting to determine whether a lambda has an explicit object parameter by checking the `LambdaScopeInfo`'s `ExplicitObjectParameter`, but it seems that that simply wasn't set (yet) by the time we got to the check. All of these should be fixed now. This fixes #70604, #79754, #84163, #84425, #86054, #86398, and #86399.
36 lines
804 B
C++
36 lines
804 B
C++
// RUN: %clang_cc1 -emit-pch -std=c++23 -o %t %s
|
|
// RUN: %clang_cc1 -include-pch %t -verify -fsyntax-only -DTEST -std=c++23 %s
|
|
|
|
// Test that dependence of 'this' and DREs due to by-value capture by a
|
|
// lambda with an explicit object parameter is serialised/deserialised
|
|
// properly.
|
|
|
|
#ifndef HEADER
|
|
#define HEADER
|
|
struct S {
|
|
int x;
|
|
auto f() {
|
|
return [*this] (this auto&&) {
|
|
int y;
|
|
x = 42;
|
|
|
|
const auto l = [y] (this auto&&) { y = 42; };
|
|
l();
|
|
};
|
|
}
|
|
};
|
|
#endif
|
|
|
|
// expected-error@* {{read-only variable is not assignable}}
|
|
// expected-error@* {{cannot assign to a variable captured by copy in a non-mutable lambda}}
|
|
// expected-note@* 2 {{in instantiation of}}
|
|
|
|
#ifdef TEST
|
|
void f() {
|
|
const auto l = S{}.f();
|
|
l(); // expected-note {{in instantiation of}}
|
|
}
|
|
#endif
|
|
|
|
|