https://gcc.gnu.org/g:61eb73a6396fd63b02f208e4288f694c849e9428

commit r16-6365-g61eb73a6396fd63b02f208e4288f694c849e9428
Author: Egas Ribeiro <[email protected]>
Date:   Mon Dec 22 22:30:12 2025 +0000

    c++: Fix ICE on partial specialization redeclaration with mismatched 
parameters [PR122958]
    
    When a partial specialization was redeclared with different template
    parameters, maybe_new_partial_specialization was incorrectly treating it
    as the same specialization by only comparing template argument lists
    without comparing template-heads. This caused an ICE when the
    redeclaration had different template parameters.
    
    Per [temp.spec.partial.general]/2, two partial specializations declare
    the same entity only if they have equivalent template-heads and
    template argument lists.
    Fix by comparing template parameter lists (template-heads) in addition
    to template argument lists when checking for existing specializations,
    and removing flag_concepts to provide diagnostics before c++20 for the
    testcase.
    
            PR c++/122958
    
    gcc/cp/ChangeLog:
    
            * pt.cc (maybe_new_partial_specialization): Compare template
            parameter lists when checking for existing specializations and
            remove flag_concepts check.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/partial-spec-redecl.C: New test.
    
    Signed-off-by: Egas Ribeiro <[email protected]>
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/pt.cc                                     |  9 +++++++--
 gcc/testsuite/g++.dg/cpp2a/partial-spec-redecl.C | 10 ++++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index ae7429b449c4..af2c7a767ab8 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -946,7 +946,7 @@ maybe_new_partial_specialization (tree& type)
      Note that we also get here for injected class names and
      late-parsed template definitions. We must ensure that we
      do not create new type declarations for those cases.  */
-  if (flag_concepts && CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
+  if (CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
     {
       tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
       tree args = CLASSTYPE_TI_ARGS (type);
@@ -979,7 +979,12 @@ maybe_new_partial_specialization (tree& type)
           tree spec_tmpl = TREE_VALUE (specs);
           tree spec_args = TREE_PURPOSE (specs);
           tree spec_constr = get_constraints (spec_tmpl);
-          if (comp_template_args (args, spec_args)
+         tree spec_parms = DECL_TEMPLATE_PARMS (spec_tmpl);
+         /* Per [temp.spec.partial.general]/2, two partial specializations
+            declare the same entity if they have equivalent template-heads
+            and template argument lists.  */
+         if (comp_template_args (args, spec_args)
+             && comp_template_parms (spec_parms, current_template_parms)
              && equivalent_constraints (type_constr, spec_constr))
            {
              type = TREE_TYPE (spec_tmpl);
diff --git a/gcc/testsuite/g++.dg/cpp2a/partial-spec-redecl.C 
b/gcc/testsuite/g++.dg/cpp2a/partial-spec-redecl.C
new file mode 100644
index 000000000000..43400191404d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/partial-spec-redecl.C
@@ -0,0 +1,10 @@
+// PR c++/122958
+// { dg-do compile }
+template <class>
+class D;
+
+template <class R, class S>
+class D<R(S)>;
+
+template <class R, class S, class Extra>
+class D<R(S)> {}; // { dg-error "template parameters not deducible" }

Reply via email to