Skip to content

Commit 6ad5f5b

Browse files
committed
Use correct sign for variant part discriminants
The discriminant value for a variant part may be signed or unsigned, depending on the type of the variant. This patch changes the DWARF reader to delay interpretation of the relevant attribute until the signed-ness is known. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32680
1 parent 0c03db9 commit 6ad5f5b

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

gdb/dwarf2/read.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -622,15 +622,21 @@ struct variant_field
622622
/* A variant can contain other variant parts. */
623623
std::vector<variant_part_builder> variant_parts;
624624

625-
/* If we see a DW_TAG_variant, then this will be set if this is the
626-
default branch. */
627-
bool default_branch = false;
628625
/* If we see a DW_AT_discr_value, then this will be the discriminant
629-
value. */
630-
ULONGEST discriminant_value = 0;
626+
value. Just the attribute is stored here, because we have to
627+
defer deciding whether the value is signed or unsigned until the
628+
end. */
629+
const attribute *discriminant_attr = nullptr;
631630
/* If we see a DW_AT_discr_list, then this is a pointer to the list
632631
data. */
633632
struct dwarf_block *discr_list_data = nullptr;
633+
634+
/* If both DW_AT_discr_value and DW_AT_discr_list are absent, then
635+
this is the default branch. */
636+
bool is_default () const
637+
{
638+
return discriminant_attr == nullptr && discr_list_data == nullptr;
639+
}
634640
};
635641

636642
/* This represents a DW_TAG_variant_part. */
@@ -10269,13 +10275,19 @@ convert_variant_range (struct obstack *obstack, const variant_field &variant,
1026910275
{
1027010276
std::vector<discriminant_range> ranges;
1027110277

10272-
if (variant.default_branch)
10278+
if (variant.is_default ())
1027310279
return {};
1027410280

1027510281
if (variant.discr_list_data == nullptr)
1027610282
{
10277-
discriminant_range r
10278-
= {variant.discriminant_value, variant.discriminant_value};
10283+
ULONGEST value;
10284+
10285+
if (is_unsigned)
10286+
value = variant.discriminant_attr->unsigned_constant ().value_or (0);
10287+
else
10288+
value = variant.discriminant_attr->signed_constant ().value_or (0);
10289+
10290+
discriminant_range r = { value, value };
1027910291
ranges.push_back (r);
1028010292
}
1028110293
else
@@ -11234,12 +11246,14 @@ handle_variant (struct die_info *die, struct type *type,
1123411246
{
1123511247
discr = dwarf2_attr (die, DW_AT_discr_list, cu);
1123611248
if (discr == nullptr || discr->as_block ()->size == 0)
11237-
variant.default_branch = true;
11249+
{
11250+
/* Nothing to do here -- default branch. */
11251+
}
1123811252
else
1123911253
variant.discr_list_data = discr->as_block ();
1124011254
}
1124111255
else
11242-
variant.discriminant_value = discr->constant_value (0);
11256+
variant.discriminant_attr = discr;
1124311257

1124411258
for (die_info *variant_child : die->children ())
1124511259
handle_struct_member_die (variant_child, type, fi, template_args, cu);

0 commit comments

Comments
 (0)