On Tue, 2016-10-11 at 06:34 -0400, Nathan Sidwell wrote: > 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?
Thanks. Various comments inline below. > 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)) Please simplify this conditional logic by breaking if up into multiple nested if statements: if (diagnostic->kind != DK_NOTE) { int count = (diagnostic_kind_count (context, DK_ERROR) + diagnostic_kind_count (context, DK_SORRY) + diagnostic_kind_count (context, DK_WERROR); or somesuch... > + >= (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); > + } 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). > 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" } */ Please can you add a comment about the dg-message directive, explaining the intent. ("Verify that with -fmax-errors that a note associated with the final error is still emitted", or somesuch"). Please can you add a testcase for -Wfatal-errors. Thanks Dave