]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Handle enumerators in name associations in Ada
authorTom Tromey <tromey@adacore.com>
Wed, 11 Feb 2026 22:05:26 +0000 (15:05 -0700)
committerTom Tromey <tromey@adacore.com>
Thu, 12 Feb 2026 21:34:24 +0000 (14:34 -0700)
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>
gdb/ada-lang.c
gdb/testsuite/gdb.ada/assoc.exp

index ae594378047772e8a10a9fe522e8e9f341e4b888..9ffe453b027206f38d9e6758f8f1db44ba3cf911 100644 (file)
@@ -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
     {
index 5d073f3a190bd7e1ab4ec14dbfb7f0579971a11a..0a2b4bd5bdab3ee7a5d706f040d8100bcfb8baa5 100644 (file)
@@ -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
        }
     }