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?