On 10/11/16 16:07, David Malcolm wrote:

This logic is running when the next diagnostic is about to be emitted.
But what if the user has selected -Wfatal-errors and there's a single
error and no further diagnostics?  Could this change the observable
behavior?  (I'm trying to think of a case here, but failing).


This version only moves the -fmax-errors handling. I've addressed your testcase comments too. WDYT?

nathan

2016-10-13  Nathan Sidwell  <nat...@acm.org>

	* diagnostic.c (diagnostic_action_after_output): Remove max error
	handling here ....
	(diagnostic_report_diagnostic): ... do it here instead.

	testsuite/
	* c-c++-common/fmax-errors.c: Make sure note is emitted.

Index: diagnostic.c
===================================================================
--- diagnostic.c	(revision 241027)
+++ diagnostic.c	(working copy)
@@ -470,18 +470,8 @@ diagnostic_action_after_output (diagnost
 	  diagnostic_finish (context);
 	  exit (FATAL_EXIT_CODE);
 	}
-      if (context->max_errors != 0
-	  && ((unsigned) (diagnostic_kind_count (context, DK_ERROR)
-			  + diagnostic_kind_count (context, DK_SORRY)
-			  + diagnostic_kind_count (context, DK_WERROR))
-	      >= context->max_errors))
-	{
-	  fnotice (stderr,
-		   "compilation terminated due to -fmax-errors=%u.\n",
-		   context->max_errors);
-	  diagnostic_finish (context);
-	  exit (FATAL_EXIT_CODE);
-	}
+      /* -fmax-error handling is just before the next diagnostic is
+	 emitted.  */
       break;
 
     case DK_ICE:
@@ -834,9 +824,7 @@ diagnostic_report_diagnostic (diagnostic
      -Wno-error=*.  */
   if (context->warning_as_error_requested
       && diagnostic->kind == DK_WARNING)
-    {
-      diagnostic->kind = DK_ERROR;
-    }
+    diagnostic->kind = DK_ERROR;
 
   if (diagnostic->option_index
       && diagnostic->option_index != permissive_error_option (context))
@@ -892,6 +880,25 @@ diagnostic_report_diagnostic (diagnostic
 	return false;
     }
 
+  if (diagnostic->kind != DK_NOTE && context->max_errors)
+    {
+      /* Check, before emitting the diagnostic, whether we would
+	 exceed the limit.  This way we will emit notes relevant to
+	 the final emitted error.  */
+      int count = (diagnostic_kind_count (context, DK_ERROR)
+		   + diagnostic_kind_count (context, DK_SORRY)
+		   + diagnostic_kind_count (context, DK_WERROR));
+
+      if ((unsigned) count >= context->max_errors)
+	{
+	  fnotice (stderr,
+		   "compilation terminated due to -fmax-errors=%u.\n",
+		   context->max_errors);
+	  diagnostic_finish (context);
+	  exit (FATAL_EXIT_CODE);
+	}
+    }
+
   context->lock++;
 
   if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
Index: testsuite/c-c++-common/fmax-errors.c
===================================================================
--- testsuite/c-c++-common/fmax-errors.c	(revision 241027)
+++ testsuite/c-c++-common/fmax-errors.c	(working copy)
@@ -1,11 +1,21 @@
 /* PR c/44782 */
 /* { dg-do compile } */
-/* { dg-options "-fmax-errors=3" } */
+/* { dg-options "-fmax-errors=3 -Wall" } */
 
 void foo (unsigned int i, unsigned int j)
 {
   (i) ();			/* { dg-error "" } */
   (j) ();			/* { dg-error "" } */
-  (i+j) ();			/* { dg-error "" } */
+
+  i + j; /* { dg-warning "" }  */
+
+  (k) ();			/* { dg-error "" } */
+  /* Make sure we see the notes related to the final error we emit.  */
+  /* { dg-message "identifier" "" { target c } 12 } */
+
+  /* Warnings after the final error should not appear.  */
+  i + j; /* no warning.  */
+
   (i*j) ();			/* no error here due to -fmax-errors */
+
 } /* { dg-prune-output "compilation terminated" } */

Reply via email to