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
This commit is contained in:
Jason Merrill 2019-12-10 15:12:50 -05:00 committed by Jason Merrill
parent 09b661cea1
commit eff66cd2aa
3 changed files with 33 additions and 14 deletions

View File

@ -1,5 +1,8 @@
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.
* class.c (build_base_field_1): Take access parameter.
(build_base_field): Likewise.

View File

@ -11052,24 +11052,25 @@ joust_maybe_elide_copy (z_candidate *&cand)
bool
cand_parms_match (z_candidate *c1, z_candidate *c2)
{
tree fn1 = c1->template_decl;
tree fn2 = c2->template_decl;
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;
}
tree fn1 = c1->fn;
tree fn2 = c2->fn;
if (fn1 == fn2)
return true;
if (identifier_p (fn1) || identifier_p (fn2))
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)),
TYPE_ARG_TYPES (TREE_TYPE (fn2)));
}

View File

@ -0,0 +1,15 @@
// { 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);