diff mbox series

[2/2] c++: Respect current_constraint_diagnosis_depth in diagnose_compound_requirement

Message ID 20200309222358.688229-2-ppalka@redhat.com
State New
Headers show
Series [1/2] c++: Replay errors during diagnosis of constraint satisfaction failures | expand

Commit Message

Patrick Palka March 9, 2020, 10:23 p.m. UTC
The first patch tries to avoid changing our current default diagnostics.  But
for the sake of consistency we arguably should also respect
current_constraint_diagnosis_depth in diagnose_compound_requirement() like we do
in the other error-replaying diagnostic routine.  But doing so would be a change
to our default diagnostics behavior, so the change has been split out into this
separate patch for separate consideration.

gcc/cp/ChangeLog:

	* constraint.cc (diagnose_compound_requirement): When diagnosing a
	compound requirement, maybe replay the satisfaction failure, subject to
	the current diagnosis depth.

gcc/testsuite/ChangeLog:

	* g++.dg/concepts/diagnostic1.C: Pass -fconcepts-diagnostics-depth=2.
	* g++.dg/concepts/diagnostic5.C: Adjust expected diagnostics.
	* g++.dg/cpp2a/concepts-requires5.C: Pass
	-fconcepts-diagnostics-depth=2.
---
 gcc/cp/constraint.cc                          | 36 ++++++++++++++-----
 gcc/testsuite/g++.dg/concepts/diagnostic1.C   |  1 +
 gcc/testsuite/g++.dg/concepts/diagnostic5.C   |  5 +--
 gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C  |  1 +
 .../g++.dg/cpp2a/concepts-requires5.C         |  2 +-
 5 files changed, 31 insertions(+), 14 deletions(-)

Comments

Li, Pan2 via Gcc-patches March 27, 2020, 4:20 a.m. UTC | #1
On Mon, 9 Mar 2020, Patrick Palka wrote:

> The first patch tries to avoid changing our current default diagnostics.  But
> for the sake of consistency we arguably should also respect
> current_constraint_diagnosis_depth in diagnose_compound_requirement() like we do
> in the other error-replaying diagnostic routine.  But doing so would be a change
> to our default diagnostics behavior, so the change has been split out into this
> separate patch for separate consideration.

Ping.  Here's a rebased version of this patch.

-- >8 --

gcc/cp/ChangeLog:

	* constraint.cc (diagnose_compound_requirement): When diagnosing a
	compound requirement, maybe replay the satisfaction failure, subject to
	the current diagnosis depth.

gcc/testsuite/ChangeLog:

	* g++.dg/concepts/diagnostic1.C: Pass -fconcepts-diagnostics-depth=2.
	* g++.dg/concepts/diagnostic5.C: Adjust expected diagnostics.
	* g++.dg/cpp2a/concepts-requires5.C: Pass
	-fconcepts-diagnostics-depth=2.
---
 gcc/cp/constraint.cc                          | 28 +++++++++++++------
 gcc/testsuite/g++.dg/concepts/diagnostic1.C   |  1 +
 gcc/testsuite/g++.dg/concepts/diagnostic5.C   |  5 +---
 gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C  |  1 +
 .../g++.dg/cpp2a/concepts-requires5.C         |  2 +-
 5 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 76c520318c3..571c7cbdd38 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3308,20 +3308,30 @@ diagnose_compound_requirement (tree req, tree args, tree in_decl)
 	  if (!type_deducible_p (expr, type, placeholder, args, quiet))
 	    {
 	      tree orig_expr = TREE_OPERAND (req, 0);
-	      inform (loc, "%qE does not satisfy return-type-requirement",
-		      orig_expr);
-
-	      /* Further explain the reason for the error.  */
-	      type_deducible_p (expr, type, placeholder, args, noisy);
+	      if (diagnosing_failed_constraint::replay_errors_p ())
+		{
+		  inform (loc,
+			  "%qE does not satisfy return-type-requirement, "
+			  "because", orig_expr);
+		  /* Further explain the reason for the error.  */
+		  type_deducible_p (expr, type, placeholder, args, noisy);
+		}
+	      else
+		inform (loc, "%qE does not satisfy return-type-requirement",
+			orig_expr);
 	    }
 	}
       else if (!expression_convertible_p (expr, type, quiet))
 	{
 	  tree orig_expr = TREE_OPERAND (req, 0);
-	  inform (loc, "cannot convert %qE to %qT", orig_expr, type);
-
-	  /* Further explain the reason for the error.  */
-	  expression_convertible_p (expr, type, noisy);
+	  if (diagnosing_failed_constraint::replay_errors_p ())
+	    {
+	      inform (loc, "cannot convert %qE to %qT because", orig_expr, type);
+	      /* Further explain the reason for the error.  */
+	      expression_convertible_p (expr, type, noisy);
+	    }
+	  else
+	    inform (loc, "cannot convert %qE to %qT", orig_expr, type);
 	}
     }
 }
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic1.C b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
index 7da08db2792..c6589e2e671 100644
--- a/gcc/testsuite/g++.dg/concepts/diagnostic1.C
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
@@ -1,6 +1,7 @@
 // PR c++/67159
 // { dg-do compile { target c++17_only } }
 // { dg-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-diagnostics-depth=2" }
 
 template <class T, class U>
 concept bool SameAs = __is_same_as(T, U);
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic5.C b/gcc/testsuite/g++.dg/concepts/diagnostic5.C
index 2641dc18423..0d890d6f548 100644
--- a/gcc/testsuite/g++.dg/concepts/diagnostic5.C
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic5.C
@@ -4,8 +4,7 @@
 template<typename T>
   concept c1 = requires { typename T::blah; };
 // { dg-message "satisfaction of .c1<T>. .with T = char." "" { target *-*-* } .-1 }
-// { dg-message "satisfaction of .c1<char\\*>." "" { target *-*-* } .-2 }
-// { dg-message ".typename T::blah. is invalid" "" { target *-*-* } .-3 }
+// { dg-message ".typename T::blah. is invalid" "" { target *-*-* } .-2 }
 
 template<typename T>
   concept c2 = requires (T x) { *x; };
@@ -27,8 +26,6 @@ template<typename T>
   concept c5 = requires (T x) { { &x } -> c1; };
 // { dg-message "satisfaction of .c5<T>. .with T = char." "" { target *-*-* } .-1 }
 // { dg-message "in requirements with .char x." "" { target *-*-* } .-2 }
-// { dg-message "does not satisfy return-type-requirement" "" { target *-*-* } .-3 }
-// { dg-error "deduced expression type does not satisfy" "" { target *-*-* } .-4 }
 
 template<typename T>
   requires (c1<T> || c2<T>) || (c3<T> || c4<T>) || c5<T> // { dg-message "49: no operand" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
index 4d521c30748..4e2d13f8eb3 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
@@ -1,5 +1,6 @@
 // PR c++/67240
 // { dg-do compile { target c++2a } }
+// { dg-additional-options "-fconcepts-diagnostics-depth=2" }
 
 template <class T, class U> concept Same = __is_same_as(T,U);
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
index 133d29e45a4..2f912b13d6a 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
@@ -1,5 +1,5 @@
 // { dg-do compile { target c++2a } }
-// { dg-additional-options -fconcepts-ts }
+// { dg-additional-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
 
 // Test conversion requirements (not in C++20)
Li, Pan2 via Gcc-patches March 27, 2020, 7:23 p.m. UTC | #2
On 3/27/20 12:20 AM, Patrick Palka wrote:
> On Mon, 9 Mar 2020, Patrick Palka wrote:
> 
>> The first patch tries to avoid changing our current default diagnostics.  But
>> for the sake of consistency we arguably should also respect
>> current_constraint_diagnosis_depth in diagnose_compound_requirement() like we do
>> in the other error-replaying diagnostic routine.  But doing so would be a change
>> to our default diagnostics behavior, so the change has been split out into this
>> separate patch for separate consideration.
> 
> Ping.  Here's a rebased version of this patch.

OK.

> -- >8 --
> 
> gcc/cp/ChangeLog:
> 
> 	* constraint.cc (diagnose_compound_requirement): When diagnosing a
> 	compound requirement, maybe replay the satisfaction failure, subject to
> 	the current diagnosis depth.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/concepts/diagnostic1.C: Pass -fconcepts-diagnostics-depth=2.
> 	* g++.dg/concepts/diagnostic5.C: Adjust expected diagnostics.
> 	* g++.dg/cpp2a/concepts-requires5.C: Pass
> 	-fconcepts-diagnostics-depth=2.
> ---
>   gcc/cp/constraint.cc                          | 28 +++++++++++++------
>   gcc/testsuite/g++.dg/concepts/diagnostic1.C   |  1 +
>   gcc/testsuite/g++.dg/concepts/diagnostic5.C   |  5 +---
>   gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C  |  1 +
>   .../g++.dg/cpp2a/concepts-requires5.C         |  2 +-
>   5 files changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> index 76c520318c3..571c7cbdd38 100644
> --- a/gcc/cp/constraint.cc
> +++ b/gcc/cp/constraint.cc
> @@ -3308,20 +3308,30 @@ diagnose_compound_requirement (tree req, tree args, tree in_decl)
>   	  if (!type_deducible_p (expr, type, placeholder, args, quiet))
>   	    {
>   	      tree orig_expr = TREE_OPERAND (req, 0);
> -	      inform (loc, "%qE does not satisfy return-type-requirement",
> -		      orig_expr);
> -
> -	      /* Further explain the reason for the error.  */
> -	      type_deducible_p (expr, type, placeholder, args, noisy);
> +	      if (diagnosing_failed_constraint::replay_errors_p ())
> +		{
> +		  inform (loc,
> +			  "%qE does not satisfy return-type-requirement, "
> +			  "because", orig_expr);
> +		  /* Further explain the reason for the error.  */
> +		  type_deducible_p (expr, type, placeholder, args, noisy);
> +		}
> +	      else
> +		inform (loc, "%qE does not satisfy return-type-requirement",
> +			orig_expr);
>   	    }
>   	}
>         else if (!expression_convertible_p (expr, type, quiet))
>   	{
>   	  tree orig_expr = TREE_OPERAND (req, 0);
> -	  inform (loc, "cannot convert %qE to %qT", orig_expr, type);
> -
> -	  /* Further explain the reason for the error.  */
> -	  expression_convertible_p (expr, type, noisy);
> +	  if (diagnosing_failed_constraint::replay_errors_p ())
> +	    {
> +	      inform (loc, "cannot convert %qE to %qT because", orig_expr, type);
> +	      /* Further explain the reason for the error.  */
> +	      expression_convertible_p (expr, type, noisy);
> +	    }
> +	  else
> +	    inform (loc, "cannot convert %qE to %qT", orig_expr, type);
>   	}
>       }
>   }
> diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic1.C b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
> index 7da08db2792..c6589e2e671 100644
> --- a/gcc/testsuite/g++.dg/concepts/diagnostic1.C
> +++ b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
> @@ -1,6 +1,7 @@
>   // PR c++/67159
>   // { dg-do compile { target c++17_only } }
>   // { dg-options "-fconcepts" }
> +// { dg-additional-options "-fconcepts-diagnostics-depth=2" }
>   
>   template <class T, class U>
>   concept bool SameAs = __is_same_as(T, U);
> diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic5.C b/gcc/testsuite/g++.dg/concepts/diagnostic5.C
> index 2641dc18423..0d890d6f548 100644
> --- a/gcc/testsuite/g++.dg/concepts/diagnostic5.C
> +++ b/gcc/testsuite/g++.dg/concepts/diagnostic5.C
> @@ -4,8 +4,7 @@
>   template<typename T>
>     concept c1 = requires { typename T::blah; };
>   // { dg-message "satisfaction of .c1<T>. .with T = char." "" { target *-*-* } .-1 }
> -// { dg-message "satisfaction of .c1<char\\*>." "" { target *-*-* } .-2 }
> -// { dg-message ".typename T::blah. is invalid" "" { target *-*-* } .-3 }
> +// { dg-message ".typename T::blah. is invalid" "" { target *-*-* } .-2 }
>   
>   template<typename T>
>     concept c2 = requires (T x) { *x; };
> @@ -27,8 +26,6 @@ template<typename T>
>     concept c5 = requires (T x) { { &x } -> c1; };
>   // { dg-message "satisfaction of .c5<T>. .with T = char." "" { target *-*-* } .-1 }
>   // { dg-message "in requirements with .char x." "" { target *-*-* } .-2 }
> -// { dg-message "does not satisfy return-type-requirement" "" { target *-*-* } .-3 }
> -// { dg-error "deduced expression type does not satisfy" "" { target *-*-* } .-4 }
>   
>   template<typename T>
>     requires (c1<T> || c2<T>) || (c3<T> || c4<T>) || c5<T> // { dg-message "49: no operand" }
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
> index 4d521c30748..4e2d13f8eb3 100644
> --- a/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
> @@ -1,5 +1,6 @@
>   // PR c++/67240
>   // { dg-do compile { target c++2a } }
> +// { dg-additional-options "-fconcepts-diagnostics-depth=2" }
>   
>   template <class T, class U> concept Same = __is_same_as(T,U);
>   
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
> index 133d29e45a4..2f912b13d6a 100644
> --- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
> @@ -1,5 +1,5 @@
>   // { dg-do compile { target c++2a } }
> -// { dg-additional-options -fconcepts-ts }
> +// { dg-additional-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
>   
>   // Test conversion requirements (not in C++20)
>   
>
diff mbox series

Patch

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c5e3d64daa6..2ad82937c7e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3282,20 +3282,38 @@  diagnose_compound_requirement (tree req, tree args, tree in_decl)
 	  if (!type_deducible_p (expr, type, placeholder, args, quiet))
 	    {
 	      tree orig_expr = TREE_OPERAND (req, 0);
-	      inform (loc, "%qE does not satisfy return-type-requirement",
-		      orig_expr);
-
-	      /* Further explain the reason for the error.  */
-	      type_deducible_p (expr, type, placeholder, args, noisy);
+	      if (current_constraint_diagnosis_depth
+		  < concepts_diagnostics_max_depth)
+		{
+		  inform (loc,
+			  "%qE does not satisfy return-type-requirement, "
+			  "because", orig_expr);
+		  /* Further explain the reason for the error.  */
+		  type_deducible_p (expr, type, placeholder, args, noisy);
+		}
+	      else
+		{
+		  inform (loc, "%qE does not satisfy return-type-requirement",
+			  orig_expr);
+		  concepts_diagnostics_max_depth_exceeded_p = true;
+		}
 	    }
 	}
       else if (!expression_convertible_p (expr, type, quiet))
 	{
 	  tree orig_expr = TREE_OPERAND (req, 0);
-	  inform (loc, "cannot convert %qE to %qT", orig_expr, type);
-
-	  /* Further explain the reason for the error.  */
-	  expression_convertible_p (expr, type, noisy);
+	  if (current_constraint_diagnosis_depth
+	      < concepts_diagnostics_max_depth)
+	    {
+	      inform (loc, "cannot convert %qE to %qT because", orig_expr, type);
+	      /* Further explain the reason for the error.  */
+	      expression_convertible_p (expr, type, noisy);
+	    }
+	  else
+	    {
+	      inform (loc, "cannot convert %qE to %qT", orig_expr, type);
+	      concepts_diagnostics_max_depth_exceeded_p = true;
+	    }
 	}
     }
 }
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic1.C b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
index 7da08db2792..c6589e2e671 100644
--- a/gcc/testsuite/g++.dg/concepts/diagnostic1.C
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic1.C
@@ -1,6 +1,7 @@ 
 // PR c++/67159
 // { dg-do compile { target c++17_only } }
 // { dg-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-diagnostics-depth=2" }
 
 template <class T, class U>
 concept bool SameAs = __is_same_as(T, U);
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic5.C b/gcc/testsuite/g++.dg/concepts/diagnostic5.C
index 3c3b42f566c..734c7fb87a6 100644
--- a/gcc/testsuite/g++.dg/concepts/diagnostic5.C
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic5.C
@@ -4,8 +4,7 @@ 
 template<typename T>
   concept c1 = requires { typename T::blah; };
 // { dg-message "satisfaction of .c1<char>." "" { target *-*-* } .-1 }
-// { dg-message "satisfaction of .c1<char\\*>." "" { target *-*-* } .-2 }
-// { dg-message ".typename T::blah. is invalid" "" { target *-*-* } .-3 }
+// { dg-message ".typename T::blah. is invalid" "" { target *-*-* } .-2 }
 
 template<typename T>
   concept c2 = requires (T x) { *x; };
@@ -27,8 +26,6 @@  template<typename T>
   concept c5 = requires (T x) { { &x } -> c1; };
 // { dg-message "satisfaction of .c5<char>." "" { target *-*-* } .-1 }
 // { dg-message "in requirements with .char x." "" { target *-*-* } .-2 }
-// { dg-message "does not satisfy return-type-requirement" "" { target *-*-* } .-3 }
-// { dg-error "deduced expression type does not satisfy" "" { target *-*-* } .-4 }
 
 template<typename T>
   requires (c1<T> || c2<T>) || (c3<T> || c4<T>) || c5<T> // { dg-message "49: no operand" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
index 4d521c30748..4e2d13f8eb3 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-iconv1.C
@@ -1,5 +1,6 @@ 
 // PR c++/67240
 // { dg-do compile { target c++2a } }
+// { dg-additional-options "-fconcepts-diagnostics-depth=2" }
 
 template <class T, class U> concept Same = __is_same_as(T,U);
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
index 133d29e45a4..2f912b13d6a 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
@@ -1,5 +1,5 @@ 
 // { dg-do compile { target c++2a } }
-// { dg-additional-options -fconcepts-ts }
+// { dg-additional-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
 
 // Test conversion requirements (not in C++20)