https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109559
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED CC| |msebor at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- Note the diagnostic is "valid" and for FilonIntegral::integrate () <bb2:> function_base::has_trivial_copy_and_destroy (&MEM[(struct function1 *)&f1].D.2804); and we're using the stmts location to diagnose this which expands to (gdb) p IS_ADHOC_LOC (location) $8 = true (gdb) p get_location_from_adhoc_loc (line_table, location) $9 = 268224 (gdb) p expand_location ($9) $10 = {file = 0x4d895d0 "", line = 5, column = 49, data = 0x0, sysp = true} so the system header flag is correct. There's if ((was_warning || diagnostic->kind == DK_WARNING) && ((!m_warn_system_headers && diagnostic->m_iinfo.m_allsyslocs) || m_inhibit_warnings)) /* Bail if the warning is not to be reported because all locations in the inlining stack (if there is one) are in system headers. */ return false; I've added -Wno-system-headers, and (gdb) p m_warn_system_headers $14 = false (gdb) p diagnostic->m_iinfo.m_allsyslocs $15 = false (gdb) p was_warning $16 = true (gdb) p m_inhibit_warnings $17 = false so the issue seems to be that the active m_set_locations_cb tree-diagnostic.cc:set_inlining_locations computes that "wrongly". The operator= associated inline block location isn't in a system header (the abstract origin, the operator= FUNCTION_DECL does have a DECL_SOURCE_LOCATION that's in a system header though). _Note_ we're assigning that BLOCK the location of the _call_ (it's for the parameter setup), _not_ the location of the callee! /* Build a block containing code to initialize the arguments, the actual inline expansion of the body, and a label for the return statements within the function to jump to. The type of the statement expression is the return type of the function call. ??? If the call does not have an associated block then we will remap all callee blocks to NULL, effectively dropping most of its debug information. This should only happen for calls to artificial decls inserted by the compiler itself. We need to either link the inlined blocks into the caller block tree or not refer to them in any way to not break GC for locations. */ if (tree block = gimple_block (stmt)) { /* We do want to assign a not UNKNOWN_LOCATION BLOCK_SOURCE_LOCATION to make inlined_function_outer_scope_p return true on this BLOCK. */ location_t loc = LOCATION_LOCUS (gimple_location (stmt)); if (loc == UNKNOWN_LOCATION) loc = LOCATION_LOCUS (DECL_SOURCE_LOCATION (fn)); if (loc == UNKNOWN_LOCATION) loc = BUILTINS_LOCATION; id->block = make_node (BLOCK); BLOCK_ABSTRACT_ORIGIN (id->block) = DECL_ORIGIN (fn); BLOCK_SOURCE_LOCATION (id->block) = loc; prepend_lexical_block (block, id->block); since this particular hook implementation was added by Martin S. I don't have high hopes of that being a concious decision. 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)) I think this should either look at DECL_SOURCE_LOCATION (ao) or at the location of the block nested in 'block'. Note we then still warn because 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) gets us the same location, failing to do loc = sysloc; ++nsyslocs; } and then ilocs.safe_push (loc); makes /* Set if all locations are in a system header. */ diagnostic->m_iinfo.m_allsyslocs = nsyslocs == ilocs.length (); fail. The logic is odd though, if it was not macro expanded it's off. The following fixes it for me. diff --git a/gcc/tree-diagnostic.cc b/gcc/tree-diagnostic.cc index a660c7d0785..a49f8939ce7 100644 --- a/gcc/tree-diagnostic.cc +++ b/gcc/tree-diagnostic.cc @@ -328,7 +328,7 @@ set_inlining_locations (diagnostic_context *, if (!diagnostic->m_iinfo.m_ao) diagnostic->m_iinfo.m_ao = block; - location_t bsloc = BLOCK_SOURCE_LOCATION (block); + location_t bsloc = DECL_SOURCE_LOCATION (ao); ilocs.safe_push (bsloc); if (in_system_header_at (bsloc)) ++nsyslocs; @@ -339,17 +339,15 @@ set_inlining_locations (diagnostic_context *, block = BLOCK_SUPERCONTEXT (block); } + location_t sysloc; + /* 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. */ 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; - } + if (in_system_header_at (loc)) + ++nsyslocs; + loc = expansion_point_location_if_in_system_header (loc); } else {