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" }
