c++: DR2303, ambiguous base deduction [PR97453]

When there are two possible matches and one is a base of the other, choose
the derived class rather than fail.

gcc/cp/ChangeLog

2020-10-21  Kamlesh Kumar  <kamleshbhalui@gmail.com>
	    Jason Merrill  <jason@redhat.com>

	PR c++/97453
	DR2303
	* pt.c (get_template_base): Consider closest base in template
	deduction when base of base also matches.

gcc/testsuite/ChangeLog

2020-10-21  Kamlesh Kumar  <kamleshbhalui@gmail.com>

	* g++.dg/DRs/dr2303.C: New test.
This commit is contained in:
kamlesh kumar 2020-11-02 20:40:21 +05:30 committed by Jason Merrill
parent a2058f5812
commit ed7f9957bb
2 changed files with 51 additions and 2 deletions

View File

@ -22699,8 +22699,20 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg,
applies. */
if (rval && !same_type_p (r, rval))
{
*result = NULL_TREE;
return tbr_ambiguous_baseclass;
/* [temp.deduct.call]/4.3: If there is a class C that is a
(direct or indirect) base class of D and derived (directly or
indirectly) from a class B and that would be a valid deduced
A, the deduced A cannot be B or pointer to B, respectively. */
if (DERIVED_FROM_P (r, rval))
/* Ignore r. */
continue;
else if (DERIVED_FROM_P (rval, r))
/* Ignore rval. */;
else
{
*result = NULL_TREE;
return tbr_ambiguous_baseclass;
}
}
rval = r;

View File

@ -0,0 +1,37 @@
// DR 2303
// PR c++/97453
// { dg-do compile { target c++11 } }
template <typename... T> struct A;
template <> struct A<>
{
};
template <typename T, typename... Ts> struct A<T, Ts...> : A<Ts...>
{
};
struct B : A<int, int>
{
};
struct C : A<int, int>, A<int> // { dg-warning "direct base .A<int>. inaccessible in .C. due to ambiguity" }
{
};
struct D : A<int>, A<int, int> // { dg-warning "direct base .A<int>. inaccessible in .D. due to ambiguity" }
{
};
template <typename... T>
void
f (const A<T...> &)
{
static_assert (sizeof...(T) == 2, "it should duduce to A<int,int>");
}
void
g ()
{
f (B{});
f (C{});
f (D{});
}