https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86208

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org,
                   |                            |nathan at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The reason why it worked in 3.2 is I think the keeping of inline function
bodies was keyed on TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) at
those times, so when emitting assembly for the main function
TREE_SYMBOL_REFERENCE has been set and when checking up deferred_fns later on
the function was seen as DECL_NEEDED_P.

Seems contemporary gcc replaces the call to the local extern decl with the
actual inline fn definition in:
  /* Map block scope extern declarations to visible declarations with the
     same name and type in outer scopes if any.  */
  if (cp_function_chain->extern_decl_map
      && VAR_OR_FUNCTION_DECL_P (stmt)
      && DECL_EXTERNAL (stmt))
    {
      struct cxx_int_tree_map *h, in;
      in.uid = DECL_UID (stmt);
      h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
      if (h)
        {
          *stmt_p = h->to;
          *walk_subtrees = 0;
          return NULL;
        }
    }

Now, if I do e.g. TREE_USED (h->to) |= TREE_USED (stmt);, the textcase works.
Not really sure if we should call mark_used here instead, or if e.g. mark_used
should use the cp_function_chain->extern_decl_map and mark not just the symbol
itself, but the hash table h->to too, whatever.  I guess it matters e.g. for
deprecated attribute, if we have:
__attribute__((deprecated ("foo"))) void foo () {}
void bar ()
{
  extern void foo ();
  foo ();
}
do we want to warn or not?

Reply via email to