diff options
author | Nathaniel Shead <nathanieloshead@gmail.com> | 2025-01-31 23:01:15 +1100 |
---|---|---|
committer | Nathaniel Shead <nathanieloshead@gmail.com> | 2025-02-14 12:14:52 +1100 |
commit | 8caf67eea7e1b29a4437f07d13c300d9fdb04827 (patch) | |
tree | 9b2124aafa685d02520cce8bce6b5243b1fc2f58 /gcc | |
parent | 12feb78be517472ca941953dce47d6e78e5a17f8 (diff) | |
download | gcc-8caf67eea7e1b29a4437f07d13c300d9fdb04827.zip gcc-8caf67eea7e1b29a4437f07d13c300d9fdb04827.tar.gz gcc-8caf67eea7e1b29a4437f07d13c300d9fdb04827.tar.bz2 |
c++: Clear lambda scope for unattached member template lambdas
In r15-7202 we made lambdas between a template parameter scope and a
class/function/initializer be considered TU-local, in lieu of working
out how to mangle them to the succeeding declaration.
I neglected to clear any existing mangling on the template declaration
however; this means that such lambdas can occasionally get a lambda
scope, and will in general inherit the lambda scope of their
instantiation context (whatever that might be).
This patch ensures that the scope is cleared on the template declaration
as well.
gcc/cp/ChangeLog:
* lambda.cc (record_lambda_scope): Clear mangling scope for
otherwise unattached lambdas in class member templates.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/lambda-uneval22.C: Add check that the primary
specialisation of the lambda is TU-local.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/lambda.cc | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/lambda-uneval22.C | 3 |
2 files changed, 13 insertions, 1 deletions
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index c612f4f..09898f6 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -1572,6 +1572,17 @@ record_lambda_scope (tree lambda) } } + /* An otherwise unattached class-scope lambda in a member template + should not have a mangling scope, as the mangling scope will not + correctly inherit on instantiation. */ + tree ctx = TYPE_CONTEXT (closure); + if (scope + && ctx + && CLASS_TYPE_P (ctx) + && ctx == TREE_TYPE (scope) + && current_template_depth > template_class_depth (ctx)) + scope = NULL_TREE; + LAMBDA_EXPR_EXTRA_SCOPE (lambda) = scope; if (scope) maybe_key_decl (scope, TYPE_NAME (closure)); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval22.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval22.C index 9c0e812..1a25a02 100644 --- a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval22.C +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval22.C @@ -5,7 +5,7 @@ struct S { using T = decltype([]{ return I; }); template <int I> - decltype([]{ return I; }) f() { return {}; } + decltype([]{ return I; }) f(); // { dg-error "declared using local type" } }; void a(S::T<0>*); // { dg-error "declared using local type" } @@ -18,4 +18,5 @@ int main() { b(nullptr); c(nullptr); d(nullptr); + S{}.f<2>()(); } |