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<int> for S<int>, we currently substitute into the lambda in the context of S<T> (rather than S<int>, which seems wrong if the above isn't wrong), so the new closure type thinks its context is S<T>, 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.
This commit is contained in:
parent
d81be519fd
commit
102a1472ab
17
gcc/cp/pt.cc
17
gcc/cp/pt.cc
@ -19724,11 +19724,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);
|
||||
|
||||
|
17
gcc/testsuite/g++.dg/cpp2a/concepts-lambda20.C
Normal file
17
gcc/testsuite/g++.dg/cpp2a/concepts-lambda20.C
Normal file
@ -0,0 +1,17 @@
|
||||
// PR c++/105652
|
||||
// { dg-do compile { target c++20 } }
|
||||
// { dg-additional-options -g }
|
||||
|
||||
template<int>
|
||||
struct I {};
|
||||
|
||||
template<class T>
|
||||
concept C = []<int N>(I<N>) { return true; } (I<0>{});
|
||||
|
||||
template<class T>
|
||||
struct S { };
|
||||
|
||||
template<C T>
|
||||
struct S<T> { constexpr static bool value = true; };
|
||||
|
||||
static_assert(S<int>::value);
|
Loading…
Reference in New Issue
Block a user