https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94469
--- Comment #12 from rguenther at suse dot de <rguenther at suse dot de> --- On Tue, 7 Apr 2020, vries at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94469 > > --- Comment #11 from Tom de Vries <vries at gcc dot gnu.org> --- > (In reply to Richard Biener from comment #9) > > (In reply to Tom de Vries from comment #8) > > > (In reply to Richard Biener from comment #7) > > > > (In reply to Richard Biener from comment #6) > > > > > Btw, I still wonder how it works with abstract functions, inline and > > > > > concrete instances. Works in gdb, that is - will dig into it a bit > > > > > after > > > > > lunch. > > > > > > > > So here I see us (without LTO) putting DW_AT_location attributes on the > > > > abstract instance copy. That kind-of makes it not abstract anymore, no? > > > > But that way we avoid emitting multiple DIEs for local statics. With > > > > -flto the same problem appears there because we cannot annotate the > > > > early CUs DIE with a location so the concrete instance copy > > > > gets [generated and] the location. > > > > > > > > So while I intended to have the early CUs behave like fully abstract > > > > the actual DWARF is different. I understand that if I emit the early > > > > CU as > > > > partial unit it becomes abstract? > > > > > > Well, that's my theory. > > > > > > I've created a minimal dwarf assembler variant corresponding to the C > > > test-case (with only var aaa), and I could reproduce the problem, however > > > after changing the tag to DW_TAG_partial_unit still a symbol table for > > > that > > > partial unit was created. It seems that the inter-cu ref handling code is > > > responsible for that. I'll try to fix this. > > > > > > > Note we do emit DW_AT_const_value > > > > to early optimized out decls - would those still be found when the > > > > early CU > > > > is partial [and not imported anywhere]? > > > > > > I think so, but I could check with the dwarf assembler test-case. > > > > OK, so that doesn't work anymore. > > > > static const int i = 1; > > > > int main() > > { > > return i; > > } > > > > with -O2 -flto -g and DW_TAG_compile_unit I see > > > > (gdb) start > > Temporary breakpoint 1 at 0x4003a0: file t.c, line 5. > > Starting program: /home/abuild/rguenther/obj-gcc-g/gcc/a.out > > > > Temporary breakpoint 1, main () at t.c:5 > > 5 return i; > > (gdb) p i > > 1 > > > > while when using DW_TAG_partial_unit: > > > > (gdb) p i > > No symbol "i" in current context. > > > > Compilation Unit @ offset 0xc7: > > Length: 0x3d (32-bit) > > Version: 4 > > Abbrev Offset: 0x64 > > Pointer Size: 8 > > <0><d2>: Abbrev Number: 1 (DW_TAG_compile_unit) > > <d3> DW_AT_producer : (indirect string, offset: 0x1d0): GNU GIMPLE > > 10.0 > > .1 20200406 (experimental) -mtune=generic -march=x86-64 -g -g -O2 -O2 > > -fno-openm > > p -fno-openacc -fno-pie -fltrans > > <d7> DW_AT_language : 12 (ANSI C99) > > <d8> DW_AT_name : (indirect string, offset: 0x250): > > <artificial> > > <dc> DW_AT_comp_dir : (indirect string, offset: 0x25d): > > /abuild/rguenth > > er/obj-gcc-g/gcc > > <e0> DW_AT_ranges : 0x40 > > <e4> DW_AT_low_pc : 0x0 > > <ec> DW_AT_stmt_list : 0xe9 > > <1><f0>: Abbrev Number: 2 (DW_TAG_subprogram) > > <f1> DW_AT_abstract_origin: <0x13c> > > <f5> DW_AT_low_pc : 0x4003a0 > > <fd> DW_AT_high_pc : 0x6 > > <105> DW_AT_frame_base : 1 byte block: 9c > > (DW_OP_call_frame_cfa) > > <107> DW_AT_GNU_all_call_sites: 1 > > <1><107>: Abbrev Number: 0 > > Compilation Unit @ offset 0x108: > > Length: 0x3d (32-bit) > > Version: 4 > > Abbrev Offset: 0x88 > > Pointer Size: 8 > > <0><113>: Abbrev Number: 1 (DW_TAG_partial_unit) > > <114> DW_AT_producer : (indirect string, offset: 0x27d): GNU C17 > > 10.0.1 > > 20200406 (experimental) -mtune=generic -march=x86-64 -g -O2 -flto > > <118> DW_AT_language : 12 (ANSI C99) > > <119> DW_AT_name : t.c > > <11d> DW_AT_comp_dir : (indirect string, offset: 0x25d): > > /abuild/rguent > > her/obj-gcc-g/gcc > > <121> DW_AT_stmt_list : 0x127 > > <1><125>: Abbrev Number: 2 (DW_TAG_variable) > > <126> DW_AT_name : i > > <128> DW_AT_decl_file : 1 > > <129> DW_AT_decl_line : 1 > > <12a> DW_AT_decl_column : 18 > > <12b> DW_AT_type : <0x137> > > <12f> DW_AT_const_value : 1 > > <1><130>: Abbrev Number: 3 (DW_TAG_base_type) > > <131> DW_AT_byte_size : 4 > > <132> DW_AT_encoding : 5 (signed) > > <133> DW_AT_name : int > > <1><137>: Abbrev Number: 4 (DW_TAG_const_type) > > <138> DW_AT_type : <0x130> > > <1><13c>: Abbrev Number: 5 (DW_TAG_subprogram) > > <13d> DW_AT_external : 1 > > <13d> DW_AT_name : (indirect string, offset: 0x2ce): main > > <141> DW_AT_decl_file : 1 > > <142> DW_AT_decl_line : 3 > > <143> DW_AT_decl_column : 5 > > <144> DW_AT_type : <0x130> > > <1><148>: Abbrev Number: 0 > > > > Ack, I've managed to reproduce this using a dwarf assembly test-case (PR > gdb/25796 - "Symbol with inherited DW_AT_const_value not found" @ > https://sourceware.org/bugzilla/show_bug.cgi?id=25796), and submitted a gdb > patch for this. Note compared to your gdb bug the case above does not have a reference to 'i' from the "real" DW_TAG_compile_unit. A an extreme dwarf testcase would probably contain a partial unit with the optimized out variable and a main unit with just a 'main' and no reference to the partial unit at all. > Note that the problem is specific to gdb's partial symbol tables feature, so > that problem doesn't occur when using -readnow. > > I understand that if I would again add imports this would likely be resolved > > but at the expense of re-creating the original issue (but just with two > > instances rather than three)? > > Agreed. OK. So I understand the DWARF standard doesn't really say how consumers should work but how do partial vs. full units differ as to "name lookup"? I've originally placed imports of original units where I instantiated something from that original unit so to make things "visible" at that point (as in, all global statics are visible by name lookup). But of course consumers do not really follow name lookup rules since I can perfectly well lookup 'i' from 'foo' for void foo() {} int i; where it is obviously not visible (but consumers do need to do something resembling name lookup when interpreting user expressions written in the source language).