Open sdnr1 opened 6 months ago
That may be what the spec says, but it's not what rustc and gdb actually do. DWARF has specified DW_AT_discr_value since DWARF 2 but gdb didn't actually use it until @tromey implemented support for Rust enums a few years ago. Was there a reason the spec wasn't followed? It looks like when DW_AT_discr_list was added a bit later it was written to use LEB128.
This part of the DWARF standard seems strange to me. It doesn't make sense to specify that the value for DW_AT_discr_value
is leb128-encoded when there is also a DWARF form associated with the value. I suppose DWARF could require only certain forms to be used here, but I don't see why that would be good.
I tend to think a DWARF bug report is in order here. I don't recall why I didn't do this back in 2018.
Requiring leb128 for DW_AT_discr_list
does make sense OTOH, since those have to be emitted using some block form.
The Rust compiler emits tagged enums and their members as
DW_TAG_variant_part
andDW_TAG_variant
DIEs in DWARF correspondingly. According to the DWARF standard, the discriminant value for each of the variant members should be LEB128 encoded. In practice, the Rust compiler does not encode these values in LEB128 encoding, thereby it is not compliant with the DWARF standard.Furthermore, there seems to be some undefined behavior with negative discriminant values. The following examples show 2 cases of tagged enums with negative discriminants.
Example 1
Discriminant type is 32 bit signed integer.
DWARF:
Example 2
Discriminant type is 64 bit signed integer.
DWARF:
Note that the form for
DW_AT_discr_value
attribute should not beDW_FORM_dataX
, rather it should beDW_FORM_sdata
.Meta
rustc --version --verbose
: