On Tue, 2021-06-15 at 17:00 -0600, Martin Sebor wrote: > On 6/11/21 11:04 AM, David Malcolm wrote: > > On Thu, 2021-06-10 at 17:26 -0600, Martin Sebor wrote: > > > This diff introduces the diagnostic infrastructure changes to > > > support > > > controlling warnings at any call site in the inlining stack and > > > printing > > > the inlining context without the %K and %G directives. > > > > Thanks for working on this, looks very promising. > > > > > Improve warning suppression for inlined functions. > > > > > > Resolves: > > > PR middle-end/98871 - Cannot silence -Wmaybe-uninitialized at > > > declaration site > > > PR middle-end/98512 - #pragma GCC diagnostic ignored ineffective in > > > conjunction with alias attribute > > > > Am I right in thinking that you add test coverage for both of these > > in > > patch 2 of the kit? > > Yes, the tests depend on the changes in patch 2 (some existing tests > fail with just patch 1 applied because the initial location passed > to warning_t() is different than with it). > >
[...] > > > > > Yep, thanks. Please see the attached revision. > > Martin Various nits inline below: > diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c > index d58586f2526..3a22d4d26a6 100644 > --- a/gcc/diagnostic.c > +++ b/gcc/diagnostic.c > @@ -991,51 +991,93 @@ print_parseable_fixits (pretty_printer *pp, > rich_location *richloc, > pp_set_prefix (pp, saved_prefix); > } > > -/* Update the diag_class of DIAGNOSTIC based on its location > - relative to any > +/* Update the inlininig context in CONTEXT for a DIAGNOSTIC. */ ^^^^^^^^^^^^^^^^^ It's inlining_info now, so please update this comment. > + > +static void > +update_inlining_context (diagnostic_context *context, > + diagnostic_info *diagnostic) ...and please rename to "get_any_inlining_info". > +{ > + auto &ilocs = diagnostic->m_iinfo.m_ilocs; > + > + if (context->set_locations_cb) > + { > + /* Retrieve the locations into which the expression about to be > + diagnosed has been inlined, including those of all the callers > + all the way down the inlining stack. */ > + context->set_locations_cb (context, diagnostic); > + location_t loc = diagnostic->m_iinfo.m_ilocs.last (); > + if (diagnostic->m_iinfo.m_ao && loc != UNKNOWN_LOCATION) > + diagnostic->message.set_location (0, loc, SHOW_RANGE_WITH_CARET); What is the purpose of the above two lines of code? (I believe it's to replace the %G/%K stuff, right?) Please can you add a suitable comment. > + } > + else > + { > + /* When there's no callback use just the one location provided > + by the caller of the diagnostic function. */ > + location_t loc = diagnostic_location (diagnostic); > + ilocs.safe_push (loc); > + diagnostic->m_iinfo.m_allsyslocs = in_system_header_at (loc); > + } > +} > + > +/* Update the kind of DIAGNOSTIC based on its location(s), including > + any of those in its inlining context, relative to any ^^^^^^^ "stack" rather than "context" here; I think we're overusing the word "context". > #pragma GCC diagnostic > directives recorded within CONTEXT. > > - Return the new diag_class of DIAGNOSTIC if it was updated, or > - DK_UNSPECIFIED otherwise. */ > + Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED > + otherwise. */ > > static diagnostic_t > update_effective_level_from_pragmas (diagnostic_context *context, > diagnostic_info *diagnostic) > { > - diagnostic_t diag_class = DK_UNSPECIFIED; > - > - if (context->n_classification_history > 0) > + if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers) > { > - location_t location = diagnostic_location (diagnostic); > + /* Ignore the diagnostic if all the inlined locations are > + in system headers and -Wno-system-headers is in effect. */ > + diagnostic->kind = DK_IGNORED; > + return DK_IGNORED; > + } > > + if (context->n_classification_history <= 0) > + return DK_UNSPECIFIED; > + > + /* Iterate over the locations, checking the diagnostic disposition > + for the diagnostic at each. If it's explicitly set as opposed > + to unspecified, update the disposition for this instance of > + the diagnostic and return it. */ > + for (location_t loc: diagnostic->m_iinfo.m_ilocs) > + { > /* FIXME: Stupid search. Optimize later. */ > for (int i = context->n_classification_history - 1; i >= 0; i --) > { > - if (linemap_location_before_p > - (line_table, > - context->classification_history[i].location, > - location)) > + const diagnostic_classification_change_t &hist > + = context->classification_history[i]; > + > + location_t pragloc = hist.location; > + if (!linemap_location_before_p (line_table, pragloc, loc)) > + continue; > + > + if (hist.kind == (int) DK_POP) > { > - if (context->classification_history[i].kind == (int) DK_POP) > - { > - i = context->classification_history[i].option; > - continue; > - } > - int option = context->classification_history[i].option; > - /* The option 0 is for all the diagnostics. */ > - if (option == 0 || option == diagnostic->option_index) > - { > - diag_class = context->classification_history[i].kind; > - if (diag_class != DK_UNSPECIFIED) > - diagnostic->kind = diag_class; > - break; > - } > + /* Move on to the next region. */ > + i = hist.option; > + continue; > + } > + > + int option = hist.option; > + /* The option 0 is for all the diagnostics. */ > + if (option == 0 || option == diagnostic->option_index) > + { > + diagnostic_t kind = hist.kind; > + if (kind != DK_UNSPECIFIED) > + diagnostic->kind = kind; > + return kind; > } > } > } > > - return diag_class; > + return DK_UNSPECIFIED; > } > > /* Generate a URL string describing CWE. The caller is responsible for > @@ -1129,6 +1171,9 @@ static bool > diagnostic_enabled (diagnostic_context *context, > diagnostic_info *diagnostic) > { > + /* Update the inlining context for this diagnostic. */ > + update_inlining_context (context, diagnostic); Please rename as described above. [...] Dave