]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: UNBOUND_CLASS_TEMPLATE context substitution [PR119981]
authorPatrick Palka <ppalka@redhat.com>
Wed, 30 Apr 2025 14:54:23 +0000 (10:54 -0400)
committerPatrick Palka <ppalka@redhat.com>
Wed, 30 Apr 2025 14:54:23 +0000 (10:54 -0400)
commit05ea8baf6ff96c77a9a2467d5c45b1ed575fca92
tree9a1eee26e4be5ebbcf6937e02c8352d4e1e8c626
parent5f44fcdfe18e72f2900d2757375843e88d32c535
c++: UNBOUND_CLASS_TEMPLATE context substitution [PR119981]

In r15-123 and r14-11434 we unconditionally set processing_template_decl
when substituting the context of an UNBOUND_CLASS_TEMPLATE, in order to
handle instantiation of the dependently scoped friend declaration

  template<int N>
  template<class T>
  friend class A<N>::B;

where the scope A<N> remains dependent after instantiation.  But this
turns out to misbehave for the UNBOUND_CLASS_TEMPLATE in the below
testcase representing

  g<[]{}>::template fn

since with the flag set substituting the args of test3 into the lambda
causes us to defer the substitution and yield a lambda that still looks
dependent, which in turn makes g<[]{}> still dependent and not suitable
for qualified name lookup.

This patch restricts setting processing_template_decl during
UNBOUND_CLASS_TEMPLATE substitution to the case where there are multiple
levels of introduced template parameters, as in the friend declaration.
(This means we need to substitute the template parameter list(s) first,
which makes sense since they lexically appear first.)

PR c++/119981
PR c++/119378

gcc/cp/ChangeLog:

* pt.cc (tsubst) <case UNBOUND_CLASS_TEMPLATE>: Substitute
into template parameter list first.  When substituting the
context, only set processing_template_decl if there's more
than one level of introduced template parameters.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/lambda-targ15.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp2a/lambda-targ15.C [new file with mode: 0644]