Fix Ada crash with .debug_types
PR ada/25875 concerns a gdb crash when gdb.ada/arr_enum_idx_w_gap.exp is run using the .debug_types board. The problem turns out to be caused by weird compiler output. In this test, the compiler emits a top-level type that refers to an enumeration type which is nested in a function. However, this function is just a declaration. This results in gdb calling read_enumeration_type for the enum type, but process_enumeration_scope is never called, yielding an enum with no fields. This causes the crash. This patch fixes the problem by arranging to create the enum fields in read_enumeration_type. Tested on x86-64 Fedora 30. gdb/ChangeLog 2020-04-29 Tom Tromey <tromey@adacore.com> PR ada/25875: * dwarf2/read.c (update_enumeration_type_from_children): Compute type fields here. (read_enumeration_type): Call update_enumeration_type_from_children later. Update comments. (process_enumeration_scope): Don't create type fields.
This commit is contained in:
parent
b68b1b58d6
commit
ed6aceddf5
@ -1,3 +1,12 @@
|
|||||||
|
2020-04-29 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
|
PR ada/25875:
|
||||||
|
* dwarf2/read.c (update_enumeration_type_from_children): Compute
|
||||||
|
type fields here.
|
||||||
|
(read_enumeration_type): Call
|
||||||
|
update_enumeration_type_from_children later. Update comments.
|
||||||
|
(process_enumeration_scope): Don't create type fields.
|
||||||
|
|
||||||
2020-04-29 Kamil Rytarowski <n54@gmx.com>
|
2020-04-29 Kamil Rytarowski <n54@gmx.com>
|
||||||
|
|
||||||
* nbsd-tdep.c: Include "xml-syscall.h".
|
* nbsd-tdep.c: Include "xml-syscall.h".
|
||||||
|
@ -15790,8 +15790,9 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assuming DIE is an enumeration type, and TYPE is its associated type,
|
/* Assuming DIE is an enumeration type, and TYPE is its associated
|
||||||
update TYPE using some information only available in DIE's children. */
|
type, update TYPE using some information only available in DIE's
|
||||||
|
children. In particular, the fields are computed. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_enumeration_type_from_children (struct die_info *die,
|
update_enumeration_type_from_children (struct die_info *die,
|
||||||
@ -15803,6 +15804,7 @@ update_enumeration_type_from_children (struct die_info *die,
|
|||||||
int flag_enum = 1;
|
int flag_enum = 1;
|
||||||
|
|
||||||
auto_obstack obstack;
|
auto_obstack obstack;
|
||||||
|
std::vector<struct field> fields;
|
||||||
|
|
||||||
for (child_die = die->child;
|
for (child_die = die->child;
|
||||||
child_die != NULL && child_die->tag;
|
child_die != NULL && child_die->tag;
|
||||||
@ -15838,10 +15840,19 @@ update_enumeration_type_from_children (struct die_info *die,
|
|||||||
flag_enum = 0;
|
flag_enum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we already know that the enum type is neither unsigned, nor
|
fields.emplace_back ();
|
||||||
a flag type, no need to look at the rest of the enumerates. */
|
struct field &field = fields.back ();
|
||||||
if (!unsigned_enum && !flag_enum)
|
FIELD_NAME (field) = dwarf2_physname (name, child_die, cu);
|
||||||
break;
|
SET_FIELD_ENUMVAL (field, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fields.empty ())
|
||||||
|
{
|
||||||
|
TYPE_NFIELDS (type) = fields.size ();
|
||||||
|
TYPE_FIELDS (type) = (struct field *)
|
||||||
|
TYPE_ALLOC (type, sizeof (struct field) * fields.size ());
|
||||||
|
memcpy (TYPE_FIELDS (type), fields.data (),
|
||||||
|
sizeof (struct field) * fields.size ());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unsigned_enum)
|
if (unsigned_enum)
|
||||||
@ -15909,11 +15920,6 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||||||
if (die_is_declaration (die, cu))
|
if (die_is_declaration (die, cu))
|
||||||
TYPE_STUB (type) = 1;
|
TYPE_STUB (type) = 1;
|
||||||
|
|
||||||
/* Finish the creation of this type by using the enum's children.
|
|
||||||
We must call this even when the underlying type has been provided
|
|
||||||
so that we can determine if we're looking at a "flag" enum. */
|
|
||||||
update_enumeration_type_from_children (die, type, cu);
|
|
||||||
|
|
||||||
/* If this type has an underlying type that is not a stub, then we
|
/* If this type has an underlying type that is not a stub, then we
|
||||||
may use its attributes. We always use the "unsigned" attribute
|
may use its attributes. We always use the "unsigned" attribute
|
||||||
in this situation, because ordinarily we guess whether the type
|
in this situation, because ordinarily we guess whether the type
|
||||||
@ -15935,7 +15941,15 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||||||
|
|
||||||
TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
|
TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
|
||||||
|
|
||||||
return set_die_type (die, type, cu);
|
set_die_type (die, type, cu);
|
||||||
|
|
||||||
|
/* Finish the creation of this type by using the enum's children.
|
||||||
|
Note that, as usual, this must come after set_die_type to avoid
|
||||||
|
infinite recursion when trying to compute the names of the
|
||||||
|
enumerators. */
|
||||||
|
update_enumeration_type_from_children (die, type, cu);
|
||||||
|
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given a pointer to a die which begins an enumeration, process all
|
/* Given a pointer to a die which begins an enumeration, process all
|
||||||
@ -15956,8 +15970,6 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
|
|||||||
if (die->child != NULL)
|
if (die->child != NULL)
|
||||||
{
|
{
|
||||||
struct die_info *child_die;
|
struct die_info *child_die;
|
||||||
struct symbol *sym;
|
|
||||||
std::vector<struct field> fields;
|
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
child_die = die->child;
|
child_die = die->child;
|
||||||
@ -15971,30 +15983,11 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
|
|||||||
{
|
{
|
||||||
name = dwarf2_name (child_die, cu);
|
name = dwarf2_name (child_die, cu);
|
||||||
if (name)
|
if (name)
|
||||||
{
|
new_symbol (child_die, this_type, cu);
|
||||||
sym = new_symbol (child_die, this_type, cu);
|
|
||||||
|
|
||||||
fields.emplace_back ();
|
|
||||||
struct field &field = fields.back ();
|
|
||||||
|
|
||||||
FIELD_NAME (field) = sym->linkage_name ();
|
|
||||||
FIELD_TYPE (field) = NULL;
|
|
||||||
SET_FIELD_ENUMVAL (field, SYMBOL_VALUE (sym));
|
|
||||||
FIELD_BITSIZE (field) = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
child_die = child_die->sibling;
|
child_die = child_die->sibling;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fields.empty ())
|
|
||||||
{
|
|
||||||
TYPE_NFIELDS (this_type) = fields.size ();
|
|
||||||
TYPE_FIELDS (this_type) = (struct field *)
|
|
||||||
TYPE_ALLOC (this_type, sizeof (struct field) * fields.size ());
|
|
||||||
memcpy (TYPE_FIELDS (this_type), fields.data (),
|
|
||||||
sizeof (struct field) * fields.size ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are reading an enum from a .debug_types unit, and the enum
|
/* If we are reading an enum from a .debug_types unit, and the enum
|
||||||
|
Loading…
Reference in New Issue
Block a user