diff mbox

fix -fmax-errors & notes, take 2

Message ID ab069b3a-0f6f-c5f1-e134-5ba97df8ad6e@acm.org
State New
Headers show

Commit Message

Nathan Sidwell Dec. 5, 2016, 12:26 p.m. UTC
On 12/02/2016 09:07 AM, Bernd Schmidt wrote:

> Arguments should be documented.


I really must get into the habit of adding FIXME when writing dev comments.


>> +  if (count >= (int) context->max_errors)

>

> Looks like there are some unnecessary type mismatches leading to this

> cast. Maybe declare max_errors as int and remove the cast?


Yeah, you'll see the original code had similar problems.  Fixed as you 
suggest.

committed the attached.

nathan

-- 
Nathan Sidwell
diff mbox

Patch

2016-12-05  Nathan Sidwell  <nathan@acm.org>

	gcc/
	* diagnostic.c (diagnostic_check_max_errors): New, broken out of ...
	(diagnostic_action_after_output): ... here.
	(diagnostic_report_diagnostic): Call it for non-notes.
	* diagnostic.h (struct diagnostic_context): Make max_errors signed
	int.
	(diagnostic_check_max_errors): Declare.

	gcc/fortran/
	* error.c (gfc_warning_check): Call diagnostic_check_max_errors.
	(gfc_error_check): Likewise.

	gcc/testsuite/
	* c-c++-common/fmax_errors.c: Check notes after last error are
	emitted.

Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 243253)
+++ gcc/diagnostic.c	(working copy)
@@ -446,6 +446,31 @@  bt_err_callback (void *data ATTRIBUTE_UN
 	   errnum == 0 ? "" : xstrerror (errnum));
 }
 
+/* Check if we've met the maximum error limit, and if so fatally exit
+   with a message.  CONTEXT is the context to check, and FLUSH
+   indicates whether a diagnostic_finish call is needed.  */
+
+void
+diagnostic_check_max_errors (diagnostic_context *context, bool flush)
+{
+  if (!context->max_errors)
+    return;
+
+  int count = (diagnostic_kind_count (context, DK_ERROR)
+	       + diagnostic_kind_count (context, DK_SORRY)
+	       + diagnostic_kind_count (context, DK_WERROR));
+
+  if (count >= context->max_errors)
+    {
+      fnotice (stderr,
+	       "compilation terminated due to -fmax-errors=%u.\n",
+	       context->max_errors);
+      if (flush)
+	diagnostic_finish (context);
+      exit (FATAL_EXIT_CODE);
+    }
+}
+
 /* Take any action which is expected to happen after the diagnostic
    is written out.  This function does not always return.  */
 void
@@ -470,18 +495,6 @@  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);
-	}
       break;
 
     case DK_ICE:
@@ -890,6 +903,9 @@  diagnostic_report_diagnostic (diagnostic
 	return false;
     }
 
+  if (diagnostic->kind != DK_NOTE)
+    diagnostic_check_max_errors (context);
+
   context->lock++;
 
   if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
Index: gcc/diagnostic.h
===================================================================
--- gcc/diagnostic.h	(revision 243253)
+++ gcc/diagnostic.h	(working copy)
@@ -143,7 +143,7 @@  struct diagnostic_context
   bool dc_warn_system_headers;
 
   /* Maximum number of errors to report.  */
-  unsigned int max_errors;
+  int max_errors;
 
   /* This function is called before any message is printed out.  It is
      responsible for preparing message prefix and such.  For example, it
@@ -320,6 +320,7 @@  void default_diagnostic_start_span_fn (d
 void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
 void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
 void diagnostic_action_after_output (diagnostic_context *, diagnostic_t);
+void diagnostic_check_max_errors (diagnostic_context *, bool flush = false);
 
 void diagnostic_file_cache_fini (void);
 
Index: gcc/fortran/error.c
===================================================================
--- gcc/fortran/error.c	(revision 243253)
+++ gcc/fortran/error.c	(working copy)
@@ -1226,6 +1226,7 @@  gfc_warning_check (void)
       diagnostic_action_after_output (global_dc,
 				      warningcount_buffered
 				      ? DK_WARNING : DK_ERROR);
+      diagnostic_check_max_errors (global_dc, true);
     }
 }
 
@@ -1370,6 +1371,7 @@  gfc_error_check (void)
       gcc_assert (gfc_output_buffer_empty_p (pp_error_buffer));
       pp->buffer = tmp_buffer;
       diagnostic_action_after_output (global_dc, DK_ERROR);
+      diagnostic_check_max_errors (global_dc, true);
       return true;
     }
 
Index: gcc/testsuite/c-c++-common/fmax-errors.c
===================================================================
--- gcc/testsuite/c-c++-common/fmax-errors.c	(revision 243253)
+++ gcc/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" } */