Here unification of P=Wrap<int>::type, A=Wrap<long>::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) <case RECORD_TYPE>: 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 <jason@redhat.com>
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);
--- /dev/null
+// PR c++/120161
+
+template<class T, class U>
+struct mp_list { };
+
+template<class T>
+struct Wrap { struct type { }; };
+
+struct A : mp_list<Wrap<int>::type, void>
+ , mp_list<Wrap<long>::type, void> { };
+
+template<class U>
+void f(mp_list<Wrap<int>::type, U>*);
+
+int main() {
+ A a;
+ f(&a);
+}