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.
===================================================================
@@ -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)
===================================================================
@@ -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);
===================================================================
@@ -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;
}
===================================================================
@@ -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" } */