From: Patrick Palka Date: Mon, 10 Aug 2020 13:39:29 +0000 (-0400) Subject: c++: constraints and address of template-id X-Git-Tag: releases/gcc-10.3.0~1037 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8679d8886383d77e3cc5b79b861b046e11f66a37;p=thirdparty%2Fgcc.git c++: constraints and address of template-id 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) --- diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f05f9a69900f..45efe3839d09 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; diff --git a/gcc/testsuite/g++.dg/concepts/fn8.C b/gcc/testsuite/g++.dg/concepts/fn8.C index ed9008099087..32df5a556c0f 100644 --- a/gcc/testsuite/g++.dg/concepts/fn8.C +++ b/gcc/testsuite/g++.dg/concepts/fn8.C @@ -24,5 +24,5 @@ template void g(T x) { } int main () { - g(&f); // { dg-error "no matches" } + g(&f); // { dg-error "no match" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C index 9287ab8e5d7b..bf12ee573f07 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C @@ -170,7 +170,7 @@ template void g(T x) { } void driver_3 () { g(&ok); - g(&err); // { dg-error "no matches" } + g(&err); // { 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 index 000000000000..8f00a760d7eb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn5.C @@ -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 +int f() { return 0; } + +template requires requires { T::fail(); } +auto f() { T::fail(); } + +int main() { + using U = decltype(&f); + (void)&f; + id(&f); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C index f731bac8c2a3..b88c968012b0 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C @@ -173,7 +173,7 @@ template void g(T x) { } void driver_3 () { g(&ok); - g(&err); // { dg-error "no matches" } + g(&err); // { dg-error "no match" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C index 434a5e2651b0..22372e525ae4 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C @@ -173,7 +173,7 @@ template void g(T x) { } void driver_3 () { g(&ok); - g(&err); // { dg-error "no matches" } + g(&err); // { dg-error "no match" } }