aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-diagnostic.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-07-02 16:16:31 -0600
committerMartin Sebor <msebor@redhat.com>2021-07-02 16:19:35 -0600
commit6feb628a706e86eb3f303aff388c74bdb29e7381 (patch)
treeba6a85ba22347904863dc5d156881106a9a667b8 /gcc/tree-diagnostic.c
parent9984f63aab93a370101966b7eb198dc61130b3c8 (diff)
downloadgcc-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.c68
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;
}