From 85f466ed0d4da336fadd01e43d764326cbabdecb Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 15 May 2025 11:07:53 -0400 Subject: [PATCH] c++: unifying specializations of non-primary tmpls [PR120161] Here unification of P=Wrap::type, A=Wrap::type wrongly succeeds ever since r14-4112 which made the RECORD_TYPE case of unify no longer recurse into template arguments for non-primary templates (since they're a non-deduced context) and so the int/long mismatch that makes the two types distinct goes unnoticed. In the case of (comparing specializations of) a non-primary template, unify should still go on to compare the types directly before returning success. PR c++/120161 gcc/cp/ChangeLog: * pt.cc (unify) : When comparing specializations of a non-primary template, still perform a type comparison. gcc/testsuite/ChangeLog: * g++.dg/template/unify13.C: New test. Reviewed-by: Jason Merrill (cherry picked from commit 0c430503f2849ebb20105695b8ad40d43d797c7b) --- gcc/cp/pt.cc | 6 +++--- gcc/testsuite/g++.dg/template/unify13.C | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/unify13.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 65fa85b0610..fb9b407c453 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -25299,10 +25299,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (parm)), INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (t)), UNIFY_ALLOW_NONE, explain_p); - else - return unify_success (explain_p); + gcc_checking_assert (t == arg); } - else if (!same_type_ignoring_top_level_qualifiers_p (parm, arg)) + + if (!same_type_ignoring_top_level_qualifiers_p (parm, arg)) return unify_type_mismatch (explain_p, parm, arg); return unify_success (explain_p); diff --git a/gcc/testsuite/g++.dg/template/unify13.C b/gcc/testsuite/g++.dg/template/unify13.C new file mode 100644 index 00000000000..ec7ca9d17a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify13.C @@ -0,0 +1,18 @@ +// PR c++/120161 + +template +struct mp_list { }; + +template +struct Wrap { struct type { }; }; + +struct A : mp_list::type, void> + , mp_list::type, void> { }; + +template +void f(mp_list::type, U>*); + +int main() { + A a; + f(&a); +} -- 2.47.2