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" } */