c++: P0848R3 and member function templates [PR95181]
authorPatrick Palka <ppalka@redhat.com>
Fri, 22 May 2020 14:28:19 +0000 (10:28 -0400)
committerJason Merrill <jason@redhat.com>
Fri, 29 May 2020 22:18:29 +0000 (18:18 -0400)
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.

gcc/cp/ChangeLog:

PR c++/95181
* class.c (add_method): Let special member function templates
coexist if they are not equivalently constrained, or in a class
template.

gcc/testsuite/ChangeLog:

PR c++/95181
* g++.dg/concepts/pr95181.C: New test.
* g++.dg/concepts/pr95181-2.C: New test.

Co-authored-by: Jason Merrill <jason@redhat.com>
gcc/cp/class.c
gcc/testsuite/g++.dg/concepts/pr95181-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/concepts/pr95181.C [new file with mode: 0644]

index ca492cdbd4056426f4656ce09e34581bf197c9b2..c818826a1081b7a93298705a775ca0c35efcd609 100644 (file)
@@ -1081,12 +1081,19 @@ add_method (tree type, tree method, bool via_using)
        {
           if (!equivalently_constrained (fn, method))
            {
+             if (processing_template_decl)
+               /* We can't check satisfaction in dependent context, wait until
+                  the class is instantiated.  */
+               continue;
+
              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-2.C b/gcc/testsuite/g++.dg/concepts/pr95181-2.C
new file mode 100644 (file)
index 0000000..6d67350
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-do compile { target concepts } }
+
+template<bool B> struct g {
+  g() requires B && false;
+  g() requires B;
+};
+
+g<true> b; // error
diff --git a/gcc/testsuite/g++.dg/concepts/pr95181.C b/gcc/testsuite/g++.dg/concepts/pr95181.C
new file mode 100644 (file)
index 0000000..0185c86
--- /dev/null
@@ -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;