From 221acd67ca50f8f069037e034a3250f13d75a9f5 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 26 May 2022 22:43:05 -0400 Subject: [PATCH] c++: lambda in concept [PR105652] We currently check satisfaction in the context of the constrained declaration (which may be wrong, see PR104111). When checking C for S, we currently substitute into the lambda in the context of S (rather than S, which seems wrong if the above isn't wrong), so the new closure type thinks its context is S, which confuses debug output. For the moment, let's work around all of this by overriding the context of the closure. PR c++/105652 gcc/cp/ChangeLog: * pt.cc (tsubst_lambda_expr): Don't let a namespace-scope lambda instantiate into a class-scope lambda. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-lambda20.C: New test. --- gcc/cp/pt.cc | 17 ++++++++++++----- gcc/testsuite/g++.dg/cpp2a/concepts-lambda20.C | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-lambda20.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 24bbe2f40608..f1f080531a67 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -19740,11 +19740,18 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) return error_mark_node; if (LAMBDA_EXPR_EXTRA_SCOPE (t) == NULL_TREE) - /* A lambda in a default argument outside a class gets no - LAMBDA_EXPR_EXTRA_SCOPE, as specified by the ABI. But - tsubst_default_argument calls start_lambda_scope, so we need to - specifically ignore it here, and use the global scope. */ - record_null_lambda_scope (r); + { + /* A lambda in a default argument outside a class gets no + LAMBDA_EXPR_EXTRA_SCOPE, as specified by the ABI. But + tsubst_default_argument calls start_lambda_scope, so we need to + specifically ignore it here, and use the global scope. */ + record_null_lambda_scope (r); + + /* If we're pushed into another scope (PR105652), fix it. */ + if (TYPE_NAMESPACE_SCOPE_P (TREE_TYPE (t))) + TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_NAME (type)) + = TYPE_CONTEXT (TREE_TYPE (t)); + } else record_lambda_scope (r); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-lambda20.C b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda20.C new file mode 100644 index 000000000000..40e5973176ea --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda20.C @@ -0,0 +1,17 @@ +// PR c++/105652 +// { dg-do compile { target c++20 } } +// { dg-additional-options -g } + +template +struct I {}; + +template +concept C = [](I) { return true; } (I<0>{}); + +template +struct S { }; + +template +struct S { constexpr static bool value = true; }; + +static_assert(S::value); -- 2.47.2