public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case)
@ 2020-04-03 13:22 vries at gcc dot gnu.org
  2020-04-06  6:08 ` [Bug debug/94469] " rguenth at gcc dot gnu.org
                   ` (16 more replies)
  0 siblings, 17 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-03 13:22 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 94469
           Summary: lto abstract variable emitted as concrete decl (ada
                    test-case)
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

Consider gdb testsuite test-case gdb.ada/call_pn (
https://sourceware.org/git/?p=binutils-gdb.git;a=tree;f=gdb/testsuite/gdb.ada/call_pn;hb=HEAD
), consisting of files foo.adb, pck.adb and pck.ads.

Compiled like so:
...
$ gnatmake-10 \
  --GCC=/usr/bin/gcc-10 \
  --GNATBIND=/usr/bin/gnatbind-10 \
  --GNATLINK=/usr/bin/gnatlink-10 \
  -largs --GCC=/usr/bin/gcc-10 -margs \
  src/gdb/testsuite/gdb.ada/call_pn/foo.adb \
  -g -flto -O0 -flto-partition=none -ffat-lto-objects
...

When trying to print the value of last_node_id, we get a question which symbol
to print:
...
$ gdb foo -ex "p last_node_id"
Reading symbols from foo...
Multiple matches for last_node_id
[0] cancel
[1] pck.last_node_id at src/gdb/testsuite/gdb.ada/call_pn/pck.adb:17
[2] pck.last_node_id at src/gdb/testsuite/gdb.ada/call_pn/foo.adb:17
> 
...
where 1 gives us:
...
> 1
$1 = <optimized out>
...
and 2 gives us:
...
> 2
$1 = 0
...

If we compile without lto, so just with -g, we have instead:
...
$ gdb foo -ex "p last_node_id"
$1 = 0
...

The structure of the dwarf for the lto case is:
...
 <0><15ef>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <15f5>   DW_AT_name        : <artificial>
 <1><1611>: Abbrev Number: 2 (DW_TAG_imported_unit)
    <1612>   DW_AT_import      : <0x167a>       [Abbrev Number: 1]
 <1><163f>: Abbrev Number: 5 (DW_TAG_variable)
    <1640>   DW_AT_abstract_origin: <0x16d4>
    <1644>   DW_AT_location    : 9 byte block: 3 d4 33 63 0 0 0 0 0    
(DW_OP_addr: 6333d4)
 <0><167a>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <1680>   DW_AT_name        : src/gdb/testsuite/gdb.ada/call_pn/pck.adb
 <1><16d4>: Abbrev Number: 8 (DW_TAG_variable)
    <16d5>   DW_AT_name        : pck__last_node_id
...

My understanding of DWARF is that this actually declares three symbols:
- the one for DW_TAG_compile_unit pck.adb
- the one for DW_TAG_compile_unit <artificial>
- the one resulting from the import of <pck.adb> into DW_TAG_compile_unit
  <artificial>

And, AFAIU, the way to make sure we declare just one symbol is by both:
- dropping the import, and
- changing the tag for pck.adb to DW_TAG_partial_unit.

The import was already dropped on master by commit 54af95767e8 "debug/94450 -
remove DW_TAG_imported_unit generated in LTRANS units" ( see PR 94450 comment 6
).

Note: interestingly, the foo.adb here is incorrect:
...
[1] pck.last_node_id at src/gdb/testsuite/gdb.ada/call_pn/pck.adb:17
[2] pck.last_node_id at src/gdb/testsuite/gdb.ada/call_pn/foo.adb:17
...
For now I'm assuming that's a gdb PR, filed as 
PR gdb/25771 - "Inter-cu DW_AT_abstract_origin results in wrong file".

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
@ 2020-04-06  6:08 ` rguenth at gcc dot gnu.org
  2020-04-06  9:32 ` vries at gcc dot gnu.org
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-06  6:08 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rguenth at gcc dot gnu.org

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Do you know under which circumstances gdb asks which symbol to print?  Because
I've never seen this for C or C++ and it should be present for _all_ global
variables when LTO is used and your analysis is correct.

Or does Ada somehow not have variable shadowing and for C and C++ gdb
implements
shadowing rules, picking the "last" instance?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
  2020-04-06  6:08 ` [Bug debug/94469] " rguenth at gcc dot gnu.org
@ 2020-04-06  9:32 ` vries at gcc dot gnu.org
  2020-04-06  9:35 ` rguenth at gcc dot gnu.org
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-06  9:32 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #1)
> Do you know under which circumstances gdb asks which symbol to print? 
> Because
> I've never seen this for C or C++ and it should be present for _all_ global
> variables when LTO is used and your analysis is correct.
> 

The choice in printing is Ada-specific, for C/C++ it picks one.

> Or does Ada somehow not have variable shadowing and for C and C++ gdb
> implements
> shadowing rules, picking the "last" instance?

Unfortunately I have no knowledge of Ada as a language as such, so I cannot
comment on that.

As for which instance is found if there are two matches for C/C++, I'm not sure
if there are any guarantees.

---

Having said that, asking which match to print is Ada-specific, listing all
variables is not, and when doing that we get two variables instead of one:
...
(gdb) info variables
   ...
File gdb.ada/call_pn/foo.adb:
17:     static pck.last_node_id: pck.node_id;

File gdb.ada/call_pn/pck.adb:
17:     static pck.last_node_id: pck.node_id;
...
So, this might be a way to reproduce the problem outside of Ada.

I tried the following C test-case:
...
$ cat test.c
static int aaa;
int
main (void)
{  
  return 0;
}
$ cat test2.c
static int bbb;
$ cat test3.c
static int ccc;
...
and compiled using:
...
$ gcc-10 -g test.c test2.c test3.c -flto -flto-partition=none -ffat-lto-objects
-O0
...
and we have again duplicate variables (for bbb and ccc):
...
$ gdb.sh a.out
Reading symbols from a.out...
(gdb) info variables
All defined variables:

File init.c:
24:     const int _IO_stdin_used;

File test.c:
1:      static int aaa;
1:      static int bbb;
1:      static int ccc;

File test2.c:
1:      static int bbb;

File test3.c:
1:      static int ccc;
...

This seems to be the same issue to me.

Even more clearly, we cannot print the values of bbb and ccc:
...
$ gdb a.out
Reading symbols from a.out...
(gdb) p aaa
$1 = 0
(gdb) p bbb
$2 = <optimized out>
(gdb) p ccc
$3 = <optimized out>
...
because the one without DW_AT_location is shadowing the one with
DW_AT_location.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
  2020-04-06  6:08 ` [Bug debug/94469] " rguenth at gcc dot gnu.org
  2020-04-06  9:32 ` vries at gcc dot gnu.org
@ 2020-04-06  9:35 ` rguenth at gcc dot gnu.org
  2020-04-06  9:49 ` vries at gcc dot gnu.org
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-06  9:35 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2020-04-06
             Status|UNCONFIRMED                 |ASSIGNED
     Ever confirmed|0                           |1
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot gnu.org

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ah, thanks for the hints - that's something I can work with more easily than an
Ada testcase ;)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2020-04-06  9:35 ` rguenth at gcc dot gnu.org
@ 2020-04-06  9:49 ` vries at gcc dot gnu.org
  2020-04-06  9:54 ` vries at gcc dot gnu.org
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-06  9:49 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Tom de Vries from comment #2)
(In reply to Richard Biener from comment #3)
> Ah, thanks for the hints - that's something I can work with more easily than
> an Ada testcase ;)

Sure :)

FWIW, the gdb behaviour is somewhat flaky, so this reproduces what I had:
...
$ gdb -batch a.out -ex "p aaa" -ex "p bbb" -ex "p ccc"
$1 = 0
$2 = <optimized out>
$3 = <optimized out>
...
but if I drop printing aaa, I do get the value of bbb:
...
$ gdb -batch a.out -ex "p bbb" -ex "p ccc"
$1 = 0
$2 = <optimized out>
...
So this also seems to interact with partial symbol tables.

To reproduce this reliably, just skip partial symbols tables using -readnow:
...
$ gdb -readnow -batch a.out -ex "p aaa" -ex "p bbb" -ex "p ccc"
$1 = <optimized out>
$2 = <optimized out>
$3 = <optimized out>
...
and now also the problem surfaces for aaa.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2020-04-06  9:49 ` vries at gcc dot gnu.org
@ 2020-04-06  9:54 ` vries at gcc dot gnu.org
  2020-04-06  9:56 ` rguenth at gcc dot gnu.org
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-06  9:54 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Tom de Vries from comment #4)
> (In reply to Tom de Vries from comment #2)
> (In reply to Richard Biener from comment #3)
> $ gdb -readnow -batch a.out -ex "p aaa" -ex "p bbb" -ex "p ccc"
> $1 = <optimized out>
> $2 = <optimized out>
> $3 = <optimized out>
> ...
> and now also the problem surfaces for aaa.

And, it's good to realize that once you set the context to main, things do
work:
...
$ gdb.sh -readnow -batch a.out -ex start -ex "p aaa" -ex "p bbb" -ex "p ccc" 
Temporary breakpoint 1 at 0x400496: file test.c, line 6.

Temporary breakpoint 1, main () at test.c:6
6         return 0;
$1 = 0
$2 = 0
$3 = 0
...

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2020-04-06  9:54 ` vries at gcc dot gnu.org
@ 2020-04-06  9:56 ` rguenth at gcc dot gnu.org
  2020-04-06 10:44 ` rguenth at gcc dot gnu.org
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-06  9:56 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
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.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2020-04-06  9:56 ` rguenth at gcc dot gnu.org
@ 2020-04-06 10:44 ` rguenth at gcc dot gnu.org
  2020-04-06 11:27 ` vries at gcc dot gnu.org
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-06 10:44 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
(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?  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]?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2020-04-06 10:44 ` rguenth at gcc dot gnu.org
@ 2020-04-06 11:27 ` vries at gcc dot gnu.org
  2020-04-06 11:38 ` rguenth at gcc dot gnu.org
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-06 11:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Tom de Vries <vries at gcc dot gnu.org> ---
(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.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (7 preceding siblings ...)
  2020-04-06 11:27 ` vries at gcc dot gnu.org
@ 2020-04-06 11:38 ` rguenth at gcc dot gnu.org
  2020-04-06 11:50 ` rguenth at gcc dot gnu.org
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-06 11:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
(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

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)?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (8 preceding siblings ...)
  2020-04-06 11:38 ` rguenth at gcc dot gnu.org
@ 2020-04-06 11:50 ` rguenth at gcc dot gnu.org
  2020-04-07 12:09 ` vries at gcc dot gnu.org
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-06 11:50 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> ---
It works again when re-adding the imports.  info variables then shows

File t.c:
1:      static const int i;

for the case of a single import.  When I import twice (into two CUs) I
still see only one 'i' listed (from the context of main and also when
not starting the program).

Not sure if that matches expectations.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (9 preceding siblings ...)
  2020-04-06 11:50 ` rguenth at gcc dot gnu.org
@ 2020-04-07 12:09 ` vries at gcc dot gnu.org
  2020-04-07 12:22 ` rguenther at suse dot de
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-07 12:09 UTC (permalink / raw)
  To: gcc-bugs

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 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.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (10 preceding siblings ...)
  2020-04-07 12:09 ` vries at gcc dot gnu.org
@ 2020-04-07 12:22 ` rguenther at suse dot de
  2020-04-07 13:53 ` vries at gcc dot gnu.org
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenther at suse dot de @ 2020-04-07 12:22 UTC (permalink / raw)
  To: gcc-bugs

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).

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (11 preceding siblings ...)
  2020-04-07 12:22 ` rguenther at suse dot de
@ 2020-04-07 13:53 ` vries at gcc dot gnu.org
  2020-04-07 14:09 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-07 13:53 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #13 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to rguenther@suse.de from comment #12)
> > 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.

Ah, sorry, I've misread that, thanks for pointing that out. For that case, I
think gdb behaves as expected.

That is, my mental model is:
- a PU represents a dwarf repository
- a CU represents a symtab (as well as a dwarf repository)
- an import imports dwarf from one dwarf repository into another
- an inter-cu ref does not represent an implicit import

So, if we have only i declared in a PU, and the PU is not imported, there's no
symtab with an 'i', and gdb can't find it.

If you want a symtab with an 'i', you have to add a DW_TAG_variable DIE to a
CU, with DW_AT_abstract_origin referencing the DIE in the PU (as my dwarf
assembly test-case does).

> 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.
> 

In my interpretation as decribed above, that boils down to the same: no symbol
'i' declared in any symtab.

> > 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).

I hope I managed to explained above how I see the difference.

---

It's perhaps good to follow-up at this point to the discussion related to
DW_AT_declaration (see PR94450 comment 5).

As mentioned in comment 8, I've created a minimal dwarf assembler variant
corresponding to the C test-case (with only var aaa), and I could reproduce the
problem. Then by tagging the abstract DIE with DW_AT_declaration, I managed to
fix the problem of "info variables" listing the variable twice. But well, the
fact that we keep decl in symtabs for gdb comes with a number of known issues
(which are tracked here:
https://sourceware.org/bugzilla/show_bug.cgi?id=25755).

In particular, there's PR24985 - "Cannot print value of global variable because
decl in one CU shadows def in other CU", and I was thinking we might run into
that for VLAs when we start using DW_AT_declaration.

So, I was hoping to avoid those issue by using PUs, but it seems also that
comes with its own set of issues in gdb :)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (12 preceding siblings ...)
  2020-04-07 13:53 ` vries at gcc dot gnu.org
@ 2020-04-07 14:09 ` rguenth at gcc dot gnu.org
  2020-04-07 15:18 ` vries at gcc dot gnu.org
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-07 14:09 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #14 from Richard Biener <rguenth at gcc dot gnu.org> ---
OK, so I think your interpretation of PUs and CUs and using PUs for the early
DWARF and CUs for the late DWARF fits the LTO model "good enough" with the
caveat of losing info about things that are not in any way referenced by
the late CUs.

Note what the LTO DWARF currently represents is

 a) early CUs represent the source at parsing time (thus no locations)
 b) late CUs represent generated code and data of the early CUs with caveats:
    1) not all early objects get instantiated
    2) there's not a simple correspondence between early and late CUs but
     a late CU instantiates selected items from multiple early CUs and there
     are multiple late CUs doing that

I have patches to mitigate b) 2) a bit making it a 1:N correspondence, that is,
there are N late CUs instantiating objects from a single early CU (with the
exception of inline instances).  Not sure if that helps mapping LTO reality
to DWARF terms.

So the early and late CUs together represent the program and the late CU
merely provides additional information.  For functions the mental model
of abstract instances in the early CUs plus inline and concrete instances
in the late CUs works quite well since there's nothing (yet) a consumer
can do with an abstract instance that isn't instantiated in any way
(well - it could say 'it is there but optimized out', sth we lose with
the PU apporach as well).  For global variables it works as long as we annotate
it (with the symbol for example).  For optimized out variables with a
constant value or for things like enumeral types members it breaks
(I guess esp. that is worriesome).

And to restate - with PUs but DW_TAG_imported_unit of the same PU in multiple
places we don't win anything esp. since the instantiations via abstract
origins remain.

Using DW_AT_declaration for variables and CUs instead of PUs is IMHO the
most promising approach then.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (13 preceding siblings ...)
  2020-04-07 14:09 ` rguenth at gcc dot gnu.org
@ 2020-04-07 15:18 ` vries at gcc dot gnu.org
  2020-04-07 15:27 ` vries at gcc dot gnu.org
  2020-04-08 10:47 ` rguenth at gcc dot gnu.org
  16 siblings, 0 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-07 15:18 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #15 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Tom de Vries from comment #8)
> > 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.
> 

Filed PR gdb/25798 - "symbol in non-imported PU should not appear in symtabs.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (14 preceding siblings ...)
  2020-04-07 15:18 ` vries at gcc dot gnu.org
@ 2020-04-07 15:27 ` vries at gcc dot gnu.org
  2020-04-08 10:47 ` rguenth at gcc dot gnu.org
  16 siblings, 0 replies; 18+ messages in thread
From: vries at gcc dot gnu.org @ 2020-04-07 15:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #16 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #14)
> Using DW_AT_declaration for variables and CUs instead of PUs is IMHO the
> most promising approach then.

I managed to reproduce the "Multiple matches" problem by switching the language
for the dwarf assembly test-case to ada (and using -readnow). And adding the
DW_AT_declaration at the concrete DIE fixed that problem. So yeah, that looks
promising.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Bug debug/94469] lto abstract variable emitted as concrete decl (ada test-case)
  2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
                   ` (15 preceding siblings ...)
  2020-04-07 15:27 ` vries at gcc dot gnu.org
@ 2020-04-08 10:47 ` rguenth at gcc dot gnu.org
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-08 10:47 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #17 from Richard Biener <rguenth at gcc dot gnu.org> ---
Created attachment 48241
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48241&action=edit
patch for the DW_AT_declaration idea

So this is a patch implementing DW_AT_declaration + DW_AT_specification for
globals (it's against GCC 9 but I expect it to apply to trunk as well).

Are there any other than DW_TAG_variable that are instantiations and where
an instance with a DW_AT_abstract_origin is another instantiation?  On
the GCC side CONST_DECLs might qualify (but we only handle those for
fortran, ada and D) which on the DWARF side would be DW_TAG_constant.

The interesting bit will be to get

+  if (TREE_CODE (decl) == VAR_DECL
+      && TREE_STATIC (decl)
+      && DECL_FILE_SCOPE_P (decl))

and the scope based check

+  /* What about class local statics?  What about function local
+     statics?  */
+  if (!is_unit_die (die)
+      && die->die_tag != DW_TAG_namespace)

in sync so that DW_AT_declaration and DW_AT_specification will match up
(at least a DW_AT_specification of sth not a DW_AT_declaration is invalid
DWARF, likelwise declaration with locations).
The above for sure isn't foolproof here.  If we avoid undoing the
"declarazation" until after LTO streaming we could add checking to
dwarf2out_die_ref_for_decl.

The question is also which (DWARF) contexts suffer from the multiple
instantiation issue as the comment notes.  The dwarf2out data structures
don't give us the back mapping of DIE -> decl.

The patch works on the testcases we have discussed sofar, test coverage
for other cases (variables in namespaces, class local statics,
function local statics) would need to be added.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2020-04-08 10:47 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-03 13:22 [Bug debug/94469] New: lto abstract variable emitted as concrete decl (ada test-case) vries at gcc dot gnu.org
2020-04-06  6:08 ` [Bug debug/94469] " rguenth at gcc dot gnu.org
2020-04-06  9:32 ` vries at gcc dot gnu.org
2020-04-06  9:35 ` rguenth at gcc dot gnu.org
2020-04-06  9:49 ` vries at gcc dot gnu.org
2020-04-06  9:54 ` vries at gcc dot gnu.org
2020-04-06  9:56 ` rguenth at gcc dot gnu.org
2020-04-06 10:44 ` rguenth at gcc dot gnu.org
2020-04-06 11:27 ` vries at gcc dot gnu.org
2020-04-06 11:38 ` rguenth at gcc dot gnu.org
2020-04-06 11:50 ` rguenth at gcc dot gnu.org
2020-04-07 12:09 ` vries at gcc dot gnu.org
2020-04-07 12:22 ` rguenther at suse dot de
2020-04-07 13:53 ` vries at gcc dot gnu.org
2020-04-07 14:09 ` rguenth at gcc dot gnu.org
2020-04-07 15:18 ` vries at gcc dot gnu.org
2020-04-07 15:27 ` vries at gcc dot gnu.org
2020-04-08 10:47 ` rguenth at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).