Hi,
Jonathan & I were chatting at the cauldron about how -fmax-errors kills any notes about the final error. That's because we bail out just after emitting the final error. This patch fixes the problem by bailing out just before emitting the error or warning after that.


Sure, we'll do slightly more compilation than asked for, but this is the fatal error path, so who cares how long it takes. Better to get notes to the user.

I augmented the fmax-errors testcase so that the final emitted error has a trailing note (which we now emit), and is followed by a warning (which causes us to bail).

The same logic applies to -Wfatal-errors handling.

ok?

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

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

	testsuite/
	* c-c++-common/fmax-errors.c: Add error with note.

Index: diagnostic.c
===================================================================
--- diagnostic.c	(revision 240920)
+++ diagnostic.c	(working copy)
@@ -464,24 +464,6 @@ diagnostic_action_after_output (diagnost
     case DK_SORRY:
       if (context->abort_on_error)
 	real_abort ();
-      if (context->fatal_errors)
-	{
-	  fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
-	  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);
-	}
       break;
 
     case DK_ICE:
@@ -890,6 +872,25 @@ diagnostic_report_diagnostic (diagnostic
 	return false;
     }
 
+  if (diagnostic->kind != DK_NOTE
+      && (unsigned)(diagnostic_kind_count (context, DK_ERROR)
+		    + diagnostic_kind_count (context, DK_SORRY)
+		    + diagnostic_kind_count (context, DK_WERROR))
+      >= (context->fatal_errors ? 1
+	  : context->max_errors ? context->max_errors : ~0u))
+    {
+      /* Check before emitting the diagnostic that would exceed the
+	 limit.  This way we will emit notes relevant to the final
+	 emitted error.  */
+      fnotice (stderr,
+	       context->fatal_errors
+	       ? "compilation terminated due to -Wfatal-errors.\n"
+	       : "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 240920)
+++ testsuite/c-c++-common/fmax-errors.c	(working copy)
@@ -1,11 +1,13 @@
 /* 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 "" } */
+  (k) ();			/* { dg-error "" } */
+  /* { dg-message "identifier" "" { target c } 9 } */
+  i + j; /* no warning.  */
   (i*j) ();			/* no error here due to -fmax-errors */
 } /* { dg-prune-output "compilation terminated" } */

Reply via email to