]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: ICE w/ dependently scoped template friend [PR119378]
authorPatrick Palka <ppalka@redhat.com>
Sat, 22 Mar 2025 14:18:07 +0000 (10:18 -0400)
committerPatrick Palka <ppalka@redhat.com>
Sat, 22 Mar 2025 14:18:07 +0000 (10:18 -0400)
Here we ICE during instantiation of the dependently scoped template
friend

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

ultimately because processing_template_decl isn't set during
substitution into the A<N> scope.  Since it's naturally a partial
substitution, we need to make sure the flag is set.

For GCC 15, this is already fixed similarly by r15-123.

PR c++/119378

gcc/cp/ChangeLog:

* pt.cc (tsubst) <case UNBOUND_CLASS_TEMPLATE>: Set
processing_template_decl when substituting the context.

gcc/testsuite/ChangeLog:

* g++.dg/template/friend85.C: New test.

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

index ca34ed75d659907c69242076d34cbd73ae9e9480..2efc7eb19e87a855d47ae0d0a93d289fea11d6e1 100644 (file)
@@ -16946,8 +16946,10 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case UNBOUND_CLASS_TEMPLATE:
       {
+       ++processing_template_decl;
        tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
                                     in_decl, /*entering_scope=*/1);
+       --processing_template_decl;
        tree name = TYPE_IDENTIFIER (t);
        tree parm_list = DECL_TEMPLATE_PARMS (TYPE_NAME (t));
 
diff --git a/gcc/testsuite/g++.dg/template/friend85.C b/gcc/testsuite/g++.dg/template/friend85.C
new file mode 100644 (file)
index 0000000..5cf8391
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/119378
+
+template<int N>
+struct A {
+  template<class T>
+  struct B;
+};
+
+template<class U>
+struct C {
+  template<int N>
+  template<class T>
+  friend class A<N>::B;
+};
+
+template struct C<int>;