Message ID | 20200806175221.3522941-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: constraints and address of template-id | expand |
On 8/6/20 1:52 PM, Patrick Palka wrote: > 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. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to > commit? OK for trunk and 10. > 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. > --- > gcc/cp/pt.c | 5 ++++- > gcc/testsuite/g++.dg/concepts/fn8.C | 2 +- > gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C | 2 +- > gcc/testsuite/g++.dg/cpp2a/concepts-fn5.C | 16 ++++++++++++++++ > gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C | 2 +- > gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C | 2 +- > 6 files changed, 24 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-fn5.C > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index e7496002c1c..bcfe8d146b1 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -22122,6 +22122,8 @@ resolve_overloaded_unification (tree tparms, > && !any_dependent_template_arguments_p (subargs)) > { > fn = instantiate_template (fn, subargs, tf_none); > + if (!constraints_satisfied_p (fn)) > + continue; > if (undeduced_auto_decl (fn)) > { > /* Instantiate the function to deduce its return type. */ > @@ -22268,7 +22270,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 ed900809908..32df5a556c0 100644 > --- a/gcc/testsuite/g++.dg/concepts/fn8.C > +++ b/gcc/testsuite/g++.dg/concepts/fn8.C > @@ -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" } > } > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C > index 238eb819e90..b31675d255c 100644 > --- a/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C > @@ -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 > index 00000000000..c01cedde28e > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn5.C > @@ -0,0 +1,16 @@ > +// Verify we check 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>); > +} > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C > index d28002c035a..5942ff19327 100644 > --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C > @@ -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" } > } > > > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C > index 9d47a7a083d..6f7ed1ffee4 100644 > --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C > @@ -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" } > } > > >
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e7496002c1c..bcfe8d146b1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -22122,6 +22122,8 @@ resolve_overloaded_unification (tree tparms, && !any_dependent_template_arguments_p (subargs)) { fn = instantiate_template (fn, subargs, tf_none); + if (!constraints_satisfied_p (fn)) + continue; if (undeduced_auto_decl (fn)) { /* Instantiate the function to deduce its return type. */ @@ -22268,7 +22270,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 ed900809908..32df5a556c0 100644 --- a/gcc/testsuite/g++.dg/concepts/fn8.C +++ b/gcc/testsuite/g++.dg/concepts/fn8.C @@ -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" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C index 238eb819e90..b31675d255c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C @@ -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 index 00000000000..c01cedde28e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn5.C @@ -0,0 +1,16 @@ +// Verify we check 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>); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C index d28002c035a..5942ff19327 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C @@ -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" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C index 9d47a7a083d..6f7ed1ffee4 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C @@ -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" } }