So... I've been getting my feet wet with LTO and debugging and I noticed
a seemingly unrelated yet annoying problem. On x86-64,
gcc.dg/guality/pr48437.c fails when run in LTO mode.
I've compared the dwarf output with and without LTO, and I noticed that
the DW_TAG_lexical_block is missing from the LTO case.
The relevant bit is that without LTO, we have a DW_TAG_lexical_block for
lines 3-6, which is not present in the LTO case:
1 volatile int i;
2 for (i = 3; i < 7; ++i)
3 {
4 extern int i;
5 asm volatile (NOP : : : "memory");
6 }
The reason this tag is not generated is because gen_block_die() unsets
must_output_die because there are no BLOCK_VARS associated with the BLOCK.
must_output_die = ((BLOCK_VARS (stmt) != NULL
|| BLOCK_NUM_NONLOCALIZED_VARS (stmt))
&& (TREE_USED (stmt)
|| TREE_ASM_WRITTEN (stmt)
|| BLOCK_ABSTRACT (stmt)));
And there is no block var because the streamer purposely avoided
streaming an extern block var:
/* We avoid outputting external vars or functions by reference
to the global decls section as we do not want to have them
enter decl merging. This is, of course, only for the call
for streaming BLOCK_VARS, but other callers are safe. */
/* ??? FIXME wrt SCC streaming. Drop these for now. */
if (VAR_OR_FUNCTION_DECL_P (t)
&& DECL_EXTERNAL (t))
; /* stream_write_tree_shallow_non_ref (ob, t, ref_p); */
else
stream_write_tree (ob, t, ref_p);
I naively tried to uncomment the offending line, but that brought about
other problems in DFS assertions.
I wasn't on the hunt for this, but I'm now curious. Can you (or anyone
else) pontificate on this? Do we avoid streaming extern block variables
by design?
Thanks.
Aldy