https://gcc.gnu.org/g:1bbfe788d1a76979e5be14169248bc34106e9c03

commit r14-10451-g1bbfe788d1a76979e5be14169248bc34106e9c03
Author: Patrick Palka <ppa...@redhat.com>
Date:   Wed Jul 17 11:08:35 2024 -0400

    c++: constrained partial spec type context [PR111890]
    
    maybe_new_partial_specialization wasn't propagating TYPE_CONTEXT when
    creating a new class type corresponding to a constrained partial spec,
    which do_friend relies on via template_class_depth to distinguish a
    template friend from a non-template friend, and so in the below testcase
    we were incorrectly instantiating the non-template operator+ as if it
    were a template leading to an ICE.
    
            PR c++/111890
    
    gcc/cp/ChangeLog:
    
            * pt.cc (maybe_new_partial_specialization): Propagate TYPE_CONTEXT
            to the newly created partial specialization.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/concepts-partial-spec15.C: New test.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>
    (cherry picked from commit 247335823f420eb1dd56f4bf32ac78d441f5ccc2)

Diff:
---
 gcc/cp/pt.cc                                         |  1 +
 gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec15.C | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 83638fd74b4d..80d0ca6d0dde 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -994,6 +994,7 @@ maybe_new_partial_specialization (tree& type)
       tree t = make_class_type (TREE_CODE (type));
       CLASSTYPE_DECLARED_CLASS (t) = CLASSTYPE_DECLARED_CLASS (type);
       SET_TYPE_TEMPLATE_INFO (t, build_template_info (tmpl, args));
+      TYPE_CONTEXT (t) = TYPE_CONTEXT (type);
 
       /* We only need a separate type node for storing the definition of this
         partial specialization; uses of S<T*> are unconstrained, so all are
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec15.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec15.C
new file mode 100644
index 000000000000..ad01a390fefd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec15.C
@@ -0,0 +1,20 @@
+// PR c++/111890
+// { dg-do compile { target c++20 } }
+
+template<class>
+struct A {
+  template<class T>
+  struct B { };
+
+  template<class T> requires T::value
+  struct B<T> { };
+
+  template<class T> requires (sizeof(T) == sizeof(int))
+  struct B<T> {
+    friend void operator+(B&, int) { }
+  };
+};
+
+void f(A<int>::B<int> b) {
+  b + 0;
+}

Reply via email to