diff mbox series

c++: Diagnose invalid use of member function in requires

Message ID 20200421180353.2777272-1-ppalka@redhat.com
State New
Headers show
Series c++: Diagnose invalid use of member function in requires | expand

Commit Message

Patrick Palka April 21, 2020, 6:03 p.m. UTC
This updates diagnose_valid_expression to mirror the convert_to_void check added
to tsubst_valid_expression_requirement by r10-7554.

Passes 'make check-c++', does this look OK to commit after a full
bootstrap/regtest?

gcc/cp/ChangeLog:

	PR c++/67825
	* constraint.cc (diagnose_valid_expression): Check convert_to_void here
	as well as in tsubst_valid_expression_requirement.

gcc/testsuite/ChangeLog:

	PR c++/67825
	* g++.dg/concepts/diagnostic10.C: New test.
	* g++.dg/cpp2a/concepts-pr67178.C: Adjust dg-note.
---
 gcc/cp/constraint.cc                          |  8 ++++++--
 gcc/testsuite/g++.dg/concepts/diagnostic10.C  | 18 ++++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C |  2 +-
 3 files changed, 25 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/concepts/diagnostic10.C

Comments

Jason Merrill April 21, 2020, 8:13 p.m. UTC | #1
On 4/21/20 2:03 PM, Patrick Palka wrote:
> This updates diagnose_valid_expression to mirror the convert_to_void check added
> to tsubst_valid_expression_requirement by r10-7554.
> 
> Passes 'make check-c++', does this look OK to commit after a full
> bootstrap/regtest?

OK, thanks.

> gcc/cp/ChangeLog:
> 
> 	PR c++/67825
> 	* constraint.cc (diagnose_valid_expression): Check convert_to_void here
> 	as well as in tsubst_valid_expression_requirement.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/67825
> 	* g++.dg/concepts/diagnostic10.C: New test.
> 	* g++.dg/cpp2a/concepts-pr67178.C: Adjust dg-note.
> ---
>   gcc/cp/constraint.cc                          |  8 ++++++--
>   gcc/testsuite/g++.dg/concepts/diagnostic10.C  | 18 ++++++++++++++++++
>   gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C |  2 +-
>   3 files changed, 25 insertions(+), 3 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/concepts/diagnostic10.C
> 
> diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> index d56ec101cd9..c05fafe5da1 100644
> --- a/gcc/cp/constraint.cc
> +++ b/gcc/cp/constraint.cc
> @@ -3242,7 +3242,8 @@ static tree
>   diagnose_valid_expression (tree expr, tree args, tree in_decl)
>   {
>     tree result = tsubst_expr (expr, args, tf_none, in_decl, false);
> -  if (result != error_mark_node)
> +  if (result != error_mark_node
> +      && convert_to_void (result, ICV_STATEMENT, tf_none) != error_mark_node)
>       return result;
>   
>     location_t loc = cp_expr_loc_or_input_loc (expr);
> @@ -3250,7 +3251,10 @@ diagnose_valid_expression (tree expr, tree args, tree in_decl)
>       {
>         /* Replay the substitution error.  */
>         inform (loc, "the required expression %qE is invalid, because", expr);
> -      tsubst_expr (expr, args, tf_error, in_decl, false);
> +      if (result == error_mark_node)
> +	tsubst_expr (expr, args, tf_error, in_decl, false);
> +      else
> +	convert_to_void (result, ICV_STATEMENT, tf_error);
>       }
>     else
>       inform (loc, "the required expression %qE is invalid", expr);
> diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic10.C b/gcc/testsuite/g++.dg/concepts/diagnostic10.C
> new file mode 100644
> index 00000000000..fcc6043ca93
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/concepts/diagnostic10.C
> @@ -0,0 +1,18 @@
> +// PR c++/67825
> +// { dg-do compile { target concepts } }
> +// { dg-additional-options "-fconcepts-diagnostics-depth=2" }
> +
> +template<typename T>
> +  requires requires (T t) { t.f; } // { dg-error "invalid use of non-static member function" }
> +void foo() { }
> +
> +struct S
> +{
> +  int f();
> +};
> +
> +void
> +bar()
> +{
> +  foo<S>(); // { dg-error "unsatisfied constraints" }
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
> index ff84711a7af..7154fc2b7fe 100644
> --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
> @@ -12,7 +12,7 @@ concept C0 = requires (auto x) { // { dg-error "placeholder type" }
>   template<typename T>
>   concept C1 = requires (C1 auto x) { // { dg-error "not been declared|placeholder|two or more|in requirements" }
>     x; // { dg-error "not declared" }
> -  { x } -> c; // { dg-message "not declared|does not satisfy" }
> +  { x } -> c; // { dg-message "is invalid" }
>   };
>   
>   template<typename T>
>
diff mbox series

Patch

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d56ec101cd9..c05fafe5da1 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3242,7 +3242,8 @@  static tree
 diagnose_valid_expression (tree expr, tree args, tree in_decl)
 {
   tree result = tsubst_expr (expr, args, tf_none, in_decl, false);
-  if (result != error_mark_node)
+  if (result != error_mark_node
+      && convert_to_void (result, ICV_STATEMENT, tf_none) != error_mark_node)
     return result;
 
   location_t loc = cp_expr_loc_or_input_loc (expr);
@@ -3250,7 +3251,10 @@  diagnose_valid_expression (tree expr, tree args, tree in_decl)
     {
       /* Replay the substitution error.  */
       inform (loc, "the required expression %qE is invalid, because", expr);
-      tsubst_expr (expr, args, tf_error, in_decl, false);
+      if (result == error_mark_node)
+	tsubst_expr (expr, args, tf_error, in_decl, false);
+      else
+	convert_to_void (result, ICV_STATEMENT, tf_error);
     }
   else
     inform (loc, "the required expression %qE is invalid", expr);
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic10.C b/gcc/testsuite/g++.dg/concepts/diagnostic10.C
new file mode 100644
index 00000000000..fcc6043ca93
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic10.C
@@ -0,0 +1,18 @@ 
+// PR c++/67825
+// { dg-do compile { target concepts } }
+// { dg-additional-options "-fconcepts-diagnostics-depth=2" }
+
+template<typename T>
+  requires requires (T t) { t.f; } // { dg-error "invalid use of non-static member function" }
+void foo() { }
+
+struct S
+{
+  int f();
+};
+
+void
+bar()
+{
+  foo<S>(); // { dg-error "unsatisfied constraints" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
index ff84711a7af..7154fc2b7fe 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67178.C
@@ -12,7 +12,7 @@  concept C0 = requires (auto x) { // { dg-error "placeholder type" }
 template<typename T>
 concept C1 = requires (C1 auto x) { // { dg-error "not been declared|placeholder|two or more|in requirements" }
   x; // { dg-error "not declared" }
-  { x } -> c; // { dg-message "not declared|does not satisfy" }
+  { x } -> c; // { dg-message "is invalid" }
 };
 
 template<typename T>