Bug 93988 - invalid DWARF emitted for complex integer
Summary: invalid DWARF emitted for complex integer
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-03-01 16:51 UTC by Tom Tromey
Modified: 2021-06-17 15:28 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-03-02 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Tromey 2020-03-01 16:51:24 UTC
Consider this test case:

_Complex int x = 23i;


Compile with -g and examine the resulting DWARF:

 <1><31>: Abbrev Number: 3 (DW_TAG_base_type)
    <32>   DW_AT_byte_size   : 8
    <33>   DW_AT_encoding    : 128	(HP_float80)
    <34>   DW_AT_name        : (indirect string, offset: 0x0): complex int


I was surprised to see that "HP_float80" here, but it turns out
that this is just an artifact of dwarf.def claiming:

/* HP extensions.  */
DW_ATE (DW_ATE_HP_float80, 0x80) /* Floating-point (80 bit).  */


In reality what gcc is doing is just returning:

      /* Dwarf2 doesn't know anything about complex ints, so use
	 a user defined type for it.  */
    case COMPLEX_TYPE:
      if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
	encoding = DW_ATE_complex_float;
      else
	encoding = DW_ATE_lo_user;
      break;


There are a couple of ways this could be replaced.  One would be to
give a complex base type its own DW_AT_type, holding the underlying
element type.

Another would be to pick a range, like 0xa0-0xaf, and emit
a value like 0xa0 | DW_ATE_signed.

I see in base_type_die that there are other cases that return
DW_ATE_lo_user.  These are probably also bugs.
Comment 1 Richard Biener 2020-03-02 12:00:19 UTC
I wonder if there is (or should be) sth like DW_ATE_unsupported ... using
DW_ATE_lo_user is indeed unfortunate but not wrong per-se.  Adding
a DW_ATE_GNU_complex_int might be also possible (and support that from gdb).

So I'm not sure it's invalid DWARF.  It's just colliding vendor extensions
(can gdb "switch" extensions if there are colliding ones?  does gdb autodetect
vendors?)

The other DW_ATE_lo_user uses are to _avoid_ invalid dwarf.  Using
DW_ATE_hi_user might be less prone to colliding with other vendor extensions
tho.
Comment 2 Tom Tromey 2020-03-02 14:13:04 UTC
(In reply to Richard Biener from comment #1)
> I wonder if there is (or should be) sth like DW_ATE_unsupported ... using
> DW_ATE_lo_user is indeed unfortunate but not wrong per-se.  Adding
> a DW_ATE_GNU_complex_int might be also possible (and support that from gdb).
> 
> So I'm not sure it's invalid DWARF.  It's just colliding vendor extensions
> (can gdb "switch" extensions if there are colliding ones?  does gdb
> autodetect
> vendors?)

Yeah, "invalid" was the wrong word to use.
More like, "undocumented gcc extension"; but one where the output
can't really be used.

Consider:

_Complex int x = 23i;
_Complex unsigned int y = 24i;

Here the base types can't readily be distinguished:

 <1><31>: Abbrev Number: 3 (DW_TAG_base_type)
    <32>   DW_AT_byte_size   : 8
    <33>   DW_AT_encoding    : 128      (HP_float80)
    <34>   DW_AT_name        : (indirect string, offset: 0x0): complex int
...
 <1><4c>: Abbrev Number: 3 (DW_TAG_base_type)
    <4d>   DW_AT_byte_size   : 8
    <4e>   DW_AT_encoding    : 128      (HP_float80)
    <4f>   DW_AT_name        : (indirect string, offset: 0x11): __unknown__


These have the same size and encoding, but in reality are different.

Also, I see the "__unknown__" there now -- better IMO to let gdb synthesize
a name instead.

To answer your questions, yes gdb can "vendor sniff" to see what extension to use.
This isn't desirable but is done on occasion.

Right now gdb doesn't use any of the DW_ATE_HP_* extensions, so even that wouldn't
need to be done.

However -- the code already needs to be changed, as shown above.  And if one is doing
that, one might as well avoid a clash and document the extension anyhow.