mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2026-08-27 00:26:02 -04:00
Handle enumerators in name associations in Ada
assoc.exp does this:
print pck.value := (Left => 3, Center => 7, Pck.Right => 2)
However, the test case is constructed so that "Center" has multiple
meanings: it might name the enumerator here:
type Posn is (Left, Center, Right);
or it might refer to this variable:
Center : Pck.Posn := Pck.Right;
The correct answer in this case is to pick the enumerator, because
that is the array's index type.
Originally I didn't fix this problem and instead used a kfail.
However, this same problem turned up again (in a slightly different
form) when the libgnat debuginfo was installed.
This patch fixes the bug by introducing new code in
ada_name_association::assign to handle the enumeration case.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33896
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33898
Tested-By: Tom de Vries <tdevries@suse.de>
This commit is contained in:
parent
4f13feb604
commit
af67bb32a2
2 changed files with 35 additions and 3 deletions
|
|
@ -9643,8 +9643,41 @@ ada_name_association::assign (aggregate_assigner &assigner,
|
|||
|
||||
if (ada_is_direct_array_type (assigner.lhs->type ()))
|
||||
{
|
||||
value *tem = m_val->evaluate (nullptr, assigner.exp, EVAL_NORMAL);
|
||||
index = value_as_long (tem);
|
||||
std::optional<LONGEST> enum_index;
|
||||
|
||||
/* If the array's index type has enumeration type, then simple
|
||||
names should be looked up as enumerators. */
|
||||
if (const char *name = find_name (op);
|
||||
name != nullptr)
|
||||
{
|
||||
type *idx_type
|
||||
= ada_check_typedef (assigner.lhs->type ())->index_type ();
|
||||
idx_type = get_base_type (idx_type);
|
||||
if (idx_type->code () == TYPE_CODE_ENUM)
|
||||
{
|
||||
for (const auto &field : idx_type->fields ())
|
||||
{
|
||||
const char *ename = ada_enum_name (field.name ());
|
||||
if (streq (name, ename))
|
||||
{
|
||||
enum_index = field.loc_enumval ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't find the name, that is ok -- the user
|
||||
might have written (VAR => EXPR), naming some
|
||||
variable somewhere. */
|
||||
}
|
||||
}
|
||||
|
||||
if (enum_index.has_value ())
|
||||
index = *enum_index;
|
||||
else
|
||||
{
|
||||
value *tem = m_val->evaluate (nullptr, assigner.exp, EVAL_NORMAL);
|
||||
index = value_as_long (tem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ gdb_test_multiple "print pck.value := (Left => 3, Center => 7, Pck.Right => 2)"
|
|||
pass $gdb_test_name
|
||||
}
|
||||
-wrap -re " = \\(3, 2, 2\\)" {
|
||||
setup_kfail ada/33898 *-*-*
|
||||
fail $gdb_test_name
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue