diff options
author | Martin Sebor <msebor@redhat.com> | 2021-07-02 16:16:31 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2021-07-02 16:19:35 -0600 |
commit | 6feb628a706e86eb3f303aff388c74bdb29e7381 (patch) | |
tree | ba6a85ba22347904863dc5d156881106a9a667b8 /gcc/tree-diagnostic.c | |
parent | 9984f63aab93a370101966b7eb198dc61130b3c8 (diff) | |
download | gcc-6feb628a706e86eb3f303aff388c74bdb29e7381.zip gcc-6feb628a706e86eb3f303aff388c74bdb29e7381.tar.gz gcc-6feb628a706e86eb3f303aff388c74bdb29e7381.tar.bz2 |
Improve warning suppression for inlined functions [PR98512].
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
gcc/ChangeLog:
PR middle-end/98871
PR middle-end/98512
* diagnostic.c (get_any_inlining_info): New.
(update_effective_level_from_pragmas): Handle inlining context.
(diagnostic_enabled): Same.
(diagnostic_report_diagnostic): Same.
* diagnostic.h (struct diagnostic_info): Add ctor.
(struct diagnostic_context): Add new member.
* tree-diagnostic.c (set_inlining_locations): New.
(tree_diagnostics_defaults): Set new callback pointer.
Diffstat (limited to 'gcc/tree-diagnostic.c')
-rw-r--r-- | gcc/tree-diagnostic.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c index 95b8ef3..1b636d7 100644 --- a/gcc/tree-diagnostic.c +++ b/gcc/tree-diagnostic.c @@ -305,6 +305,73 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec, return true; } +/* Set the locations of call sites along the inlining stack corresponding + to the DIAGNOSTIC location. */ + +static void +set_inlining_locations (diagnostic_context *, + diagnostic_info *diagnostic) +{ + location_t loc = diagnostic_location (diagnostic); + tree block = LOCATION_BLOCK (loc); + + /* Count the number of locations in system headers. When all are, + warnings are suppressed by -Wno-system-headers. Otherwise, they + involve some user code, possibly inlined into a function in a system + header, and are not treated as coming from system headers. */ + unsigned nsyslocs = 0; + + /* Use a reference to the vector of locations for convenience. */ + auto &ilocs = diagnostic->m_iinfo.m_ilocs; + + while (block && TREE_CODE (block) == BLOCK + && BLOCK_ABSTRACT_ORIGIN (block)) + { + tree ao = BLOCK_ABSTRACT_ORIGIN (block); + if (TREE_CODE (ao) == FUNCTION_DECL) + { + if (!diagnostic->m_iinfo.m_ao) + diagnostic->m_iinfo.m_ao = block; + + location_t bsloc = BLOCK_SOURCE_LOCATION (block); + ilocs.safe_push (bsloc); + if (in_system_header_at (bsloc)) + ++nsyslocs; + } + else if (TREE_CODE (ao) != BLOCK) + break; + + block = BLOCK_SUPERCONTEXT (block); + } + + if (ilocs.length ()) + { + /* When there is an inlining context use the macro expansion + location for the original location and bump up NSYSLOCS if + it's in a system header since it's not counted above. */ + location_t sysloc = expansion_point_location_if_in_system_header (loc); + if (sysloc != loc) + { + loc = sysloc; + ++nsyslocs; + } + } + else + { + /* When there's no inlining context use the original location + and set NSYSLOCS accordingly. */ + nsyslocs = in_system_header_at (loc) != 0; + } + + ilocs.safe_push (loc); + + /* Set if all locations are in a system header. */ + diagnostic->m_iinfo.m_allsyslocs = nsyslocs == ilocs.length (); + + if (tree *ao = pp_ti_abstract_origin (&diagnostic->message)) + *ao = (tree)diagnostic->m_iinfo.m_ao; +} + /* Sets CONTEXT to use language independent diagnostics. */ void tree_diagnostics_defaults (diagnostic_context *context) @@ -314,4 +381,5 @@ tree_diagnostics_defaults (diagnostic_context *context) diagnostic_format_decoder (context) = default_tree_printer; context->print_path = default_tree_diagnostic_path_printer; context->make_json_for_path = default_tree_make_json_for_path; + context->set_locations_cb = set_inlining_locations; } |