Commit eff66cd2 by Jason Merrill Committed by Jason Merrill

PR c++/92847 - C++20 comparison ambiguity with class template.

This testcase demonstrates that looking at cand->template_decl is not a good
starting place for finding the most general template, as it is only set for
primary templates.

	* call.c (cand_parms_match): Handle all templated functions.

From-SVN: r279185
parent 09b661ce
2019-12-10 Jason Merrill <jason@redhat.com> 2019-12-10 Jason Merrill <jason@redhat.com>
PR c++/92847 - C++20 comparison ambiguity with class template.
* call.c (cand_parms_match): Handle all templated functions.
Fix C++20 structural type vs. private base. Fix C++20 structural type vs. private base.
* class.c (build_base_field_1): Take access parameter. * class.c (build_base_field_1): Take access parameter.
(build_base_field): Likewise. (build_base_field): Likewise.
......
...@@ -11052,24 +11052,25 @@ joust_maybe_elide_copy (z_candidate *&cand) ...@@ -11052,24 +11052,25 @@ joust_maybe_elide_copy (z_candidate *&cand)
bool bool
cand_parms_match (z_candidate *c1, z_candidate *c2) cand_parms_match (z_candidate *c1, z_candidate *c2)
{ {
tree fn1 = c1->template_decl; tree fn1 = c1->fn;
tree fn2 = c2->template_decl; tree fn2 = c2->fn;
if (fn1 && fn2)
{
fn1 = most_general_template (TI_TEMPLATE (fn1));
fn1 = DECL_TEMPLATE_RESULT (fn1);
fn2 = most_general_template (TI_TEMPLATE (fn2));
fn2 = DECL_TEMPLATE_RESULT (fn2);
}
else
{
fn1 = c1->fn;
fn2 = c2->fn;
}
if (fn1 == fn2) if (fn1 == fn2)
return true; return true;
if (identifier_p (fn1) || identifier_p (fn2)) if (identifier_p (fn1) || identifier_p (fn2))
return false; return false;
/* We don't look at c1->template_decl because that's only set for primary
templates, not e.g. non-template member functions of class templates. */
tree t1 = most_general_template (fn1);
tree t2 = most_general_template (fn2);
if (t1 || t2)
{
if (!t1 || !t2)
return false;
if (t1 == t2)
return true;
fn1 = DECL_TEMPLATE_RESULT (t1);
fn2 = DECL_TEMPLATE_RESULT (t2);
}
return compparms (TYPE_ARG_TYPES (TREE_TYPE (fn1)), return compparms (TYPE_ARG_TYPES (TREE_TYPE (fn1)),
TYPE_ARG_TYPES (TREE_TYPE (fn2))); TYPE_ARG_TYPES (TREE_TYPE (fn2)));
} }
......
// { dg-do compile { target c++11 } }
template<typename T>
struct A {
A() {}
template<typename U>
A(const A<U>&) {}
bool operator==(const A&) const { return true; }
};
A<const int> a;
A<int> b;
auto c = (a == b);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment