diff mbox series

c++: constraints and address of template-id

Message ID 20200806175221.3522941-1-ppalka@redhat.com
State New
Headers show
Series c++: constraints and address of template-id | expand

Commit Message

Patrick Palka Aug. 6, 2020, 5:52 p.m. UTC
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?

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

Comments

Jason Merrill Aug. 7, 2020, 8:14 p.m. UTC | #1
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 mbox series

Patch

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" }
 }