]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: constraints and address of template-id
authorPatrick Palka <ppalka@redhat.com>
Mon, 10 Aug 2020 13:39:29 +0000 (09:39 -0400)
committerPatrick Palka <ppalka@redhat.com>
Thu, 13 Aug 2020 15:55:02 +0000 (11:55 -0400)
When resolving the address of a template-id, we need to drop functions
whose associated constraints are not satisfied, as per [over.over].  We
do so in resolve_address_of_overloaded_function, but not in
resolve_overloaded_unification or resolve_nondeduced_context, which
seems like an oversight.

gcc/cp/ChangeLog:

* pt.c (resolve_overloaded_unification): Drop functions with
unsatisfied constraints.
(resolve_nondeduced_context): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-fn5.C: New test.
* g++.dg/concepts/fn8.C: Generalize dg-error directive to accept
"no matching function ..." diagnostic.
* g++.dg/cpp2a/concepts-fn1.C: Likewise.
* g++.dg/cpp2a/concepts-ts2.C: Likewise.
* g++.dg/cpp2a/concepts-ts3.C: Likewise.

(cherry picked from commit 41fd9d26108fc98bbffce3d99d218a6a09fa80c6)

gcc/cp/pt.c
gcc/testsuite/g++.dg/concepts/fn8.C
gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C
gcc/testsuite/g++.dg/cpp2a/concepts-fn5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C
gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C

index f05f9a69900fca9604c40703d4513de6e615b99c..45efe3839d09a3f22c87b470ca25a3eda64454a8 100644 (file)
@@ -22163,7 +22163,11 @@ resolve_overloaded_unification (tree tparms,
          if (subargs != error_mark_node
              && !any_dependent_template_arguments_p (subargs))
            {
-             elem = TREE_TYPE (instantiate_template (fn, subargs, tf_none));
+             fn = instantiate_template (fn, subargs, tf_none);
+             if (!constraints_satisfied_p (fn))
+               continue;
+
+             elem = TREE_TYPE (fn);
              if (try_one_overload (tparms, targs, tempargs, parm,
                                    elem, strict, sub_strict, addr_p, explain_p)
                  && (!goodfn || !same_type_p (goodfn, elem)))
@@ -22301,7 +22305,8 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
                  badfn = fn;
                  badargs = subargs;
                }
-             else if (elem && (!goodfn || !decls_match (goodfn, elem)))
+             else if (elem && (!goodfn || !decls_match (goodfn, elem))
+                      && constraints_satisfied_p (elem))
                {
                  goodfn = elem;
                  ++good;
index ed9008099087ef2e473551507df6715c1bcdab4f..32df5a556c0f01aa7af2ea8c02ba540ed5779a9a 100644 (file)
@@ -24,5 +24,5 @@ template<typename T>
   void g(T x) { }
 
 int main () {
-  g(&f<int>); // { dg-error "no matches" }
+  g(&f<int>); // { dg-error "no match" }
 }
index 9287ab8e5d7b3cfdcb311be6b1a63cd73a8c6391..bf12ee573f07ddd73cb8e2287d5a19932a02c093 100644 (file)
@@ -170,7 +170,7 @@ template<typename T> void g(T x) { }
 void driver_3 () 
 {
   g(&ok<int>);
-  g(&err<int>); // { dg-error "no matches" }
+  g(&err<int>); // { dg-error "no match" }
 }
 
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn5.C
new file mode 100644 (file)
index 0000000..8f00a76
--- /dev/null
@@ -0,0 +1,17 @@
+// Verify we check associated constraints when resolving the address of a
+// template-id.
+// { dg-do compile { target c++20 } }
+
+void id(auto) { }
+
+template <typename>
+int f() { return 0; }
+
+template <typename T> requires requires { T::fail(); }
+auto f() { T::fail(); }
+
+int main() {
+  using U = decltype(&f<int>);
+  (void)&f<int>;
+  id(&f<int>);
+}
index f731bac8c2a3da6f8a466aced8a3c9c701607fdf..b88c968012b0eb6daaef5d67b078f8eccbda85ec 100644 (file)
@@ -173,7 +173,7 @@ template<typename T> void g(T x) { }
 void driver_3 () 
 {
   g(&ok<int>);
-  g(&err<int>); // { dg-error "no matches" }
+  g(&err<int>); // { dg-error "no match" }
 }
 
 
index 434a5e2651b015bcbe7dd4db2c8adf802dc92447..22372e525ae4f7bd7a43e1d78681b36a554c43b6 100644 (file)
@@ -173,7 +173,7 @@ template<typename T> void g(T x) { }
 void driver_3 () 
 {
   g(&ok<int>);
-  g(&err<int>); // { dg-error "no matches" }
+  g(&err<int>); // { dg-error "no match" }
 }