On Fri, 22 May 2020, Patrick Palka wrote: > When comparing two special member function templates to see if one hides > the other (as per P0848R3), we need to check satisfaction which we can't > do on templates. So this patch makes add_method skip the eligibility > test on member function templates and just lets them coexist.
It just occurred to me that this problem isn't limited to member function templates. Consider this valid testcase which we currently reject: template<bool B> struct g { g() requires B && false; g() requires B; }; g<true> b; // error During add_method, we check satisfaction of both default constructors, and since their constraints are dependent, constraints_satisfied_p returns true for both sets of constraints. We then see that 'B && false' is more constrained than 'B' and therefore discard the second constructor. Since we discarded the second default constructor at definition time, the instantiation g<true> has no eligible default constructor. I am not sure what to do from here... > > Passes 'make check-c++', does this look OK to commit to master and later > to the 10 branch? > > gcc/cp/ChangeLog: > > PR c++/95181 > * class.c (add_method): Let special member function templates > coexist if they are not equivalently constrained. > > gcc/testsuite/ChangeLog: > > PR c++/95181 > * g++.dg/concepts/pr95181.C: New test. > --- > gcc/cp/class.c | 10 ++++++---- > gcc/testsuite/g++.dg/concepts/pr95181.C | 9 +++++++++ > 2 files changed, 15 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/concepts/pr95181.C > > diff --git a/gcc/cp/class.c b/gcc/cp/class.c > index bab15524a60..cb268d191d6 100644 > --- a/gcc/cp/class.c > +++ b/gcc/cp/class.c > @@ -1079,10 +1079,12 @@ add_method (tree type, tree method, bool via_using) > { > special_function_kind sfk = special_memfn_p (method); > > - if (sfk == sfk_none || DECL_INHERITED_CTOR (fn)) > - /* Non-special member functions coexist if they are not > - equivalently constrained. A member function is not hidden > - by an inherited constructor. */ > + if (sfk == sfk_none > + || DECL_INHERITED_CTOR (fn) > + || TREE_CODE (fn) == TEMPLATE_DECL) > + /* Member function templates and non-special member functions > + coexist if they are not equivalently constrained. A member > + function is not hidden by an inherited constructor. */ > continue; > > /* P0848: For special member functions, deleted, unsatisfied, or > diff --git a/gcc/testsuite/g++.dg/concepts/pr95181.C > b/gcc/testsuite/g++.dg/concepts/pr95181.C > new file mode 100644 > index 00000000000..0185c86b438 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/concepts/pr95181.C > @@ -0,0 +1,9 @@ > +// PR c++/95181 > +// { dg-do compile { target concepts } } > + > +template <typename> struct f { > + template <typename T=int> f(); > + template <typename T=int> requires false f(); > +}; > + > +f<int> a; > -- > 2.27.0.rc1.5.gae92ac8ae3 > >