Fix cast of character to enum type in Ada
authorTom Tromey <tromey@adacore.com>
Fri, 3 May 2019 18:18:26 +0000 (12:18 -0600)
committerTom Tromey <tromey@adacore.com>
Fri, 3 May 2019 23:04:56 +0000 (17:04 -0600)
An internal bug report points out that, when a global character enum
type is used, casting fails, like:

    (gdb) print global_char_enum'('F')
    $1 = 70

The bug here turns out to be that enumerators are qualified, so for
example the mangled name might be "pck__QU48", rather than "QU48".

This patch fixes the problem by only examining the suffix of the
enumerator.  This is ok because the type is already known, and because
the mangling scheme ensures that there won't be clashes.

Tested on x86-64 Fedora 29.

gdb/ChangeLog
2019-05-03  Tom Tromey  <tromey@adacore.com>

* ada-exp.y (convert_char_literal): Check suffix of each
enumerator.

gdb/testsuite/ChangeLog
2019-05-03  Tom Tromey  <tromey@adacore.com>

* gdb.ada/char_enum/pck.ads (Global_Enum_Type): New type.
* gdb.ada/char_enum/foo.adb: Use Global_Enum_Type.
* gdb.ada/char_enum.exp: Add test.

gdb/ChangeLog
gdb/ada-exp.y
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/char_enum.exp
gdb/testsuite/gdb.ada/char_enum/foo.adb
gdb/testsuite/gdb.ada/char_enum/pck.ads

index 6fdbf675f3e5b17a2a304e5cf74b49ea8ff0a341..2172a030c7dedcf1bd3ac3216fc829232c8621eb 100644 (file)
@@ -1,3 +1,8 @@
+2019-05-03  Tom Tromey  <tromey@adacore.com>
+
+       * ada-exp.y (convert_char_literal): Check suffix of each
+       enumerator.
+
 2019-05-03  Dilyan Palauzov  <dilyan.palauzov@aegee.org>
 
        PR ada/21406:
index eb71f124848a52fd3707be96b65684a61a01f23d..92461dbcb694294232b89a399fca716669327303 100644 (file)
@@ -1407,9 +1407,17 @@ convert_char_literal (struct type *type, LONGEST val)
     return val;
 
   xsnprintf (name, sizeof (name), "QU%02x", (int) val);
+  size_t len = strlen (name);
   for (f = 0; f < TYPE_NFIELDS (type); f += 1)
     {
-      if (strcmp (name, TYPE_FIELD_NAME (type, f)) == 0)
+      /* Check the suffix because an enum constant in a package will
+        have a name like "pkg__QUxx".  This is safe enough because we
+        already have the correct type, and because mangling means
+        there can't be clashes.  */
+      const char *ename = TYPE_FIELD_NAME (type, f);
+      size_t elen = strlen (ename);
+
+      if (elen >= len && strcmp (name, ename + elen - len) == 0)
        return TYPE_FIELD_ENUMVAL (type, f);
     }
   return val;
index c5bdddb8f1c21e5612a911ed990346e3782855f4..72fc0d812107e36d49e7974286452abd622138d6 100644 (file)
@@ -1,3 +1,9 @@
+2019-05-03  Tom Tromey  <tromey@adacore.com>
+
+       * gdb.ada/char_enum/pck.ads (Global_Enum_Type): New type.
+       * gdb.ada/char_enum/foo.adb: Use Global_Enum_Type.
+       * gdb.ada/char_enum.exp: Add test.
+
 2019-05-03  Tom de Vries  <tdevries@suse.de>
 
        * boards/cc-with-gdb-index.exp: New file.
index 4b35fcb5ac43685330862f73969dc5f7793e7607..c37d696f66d02d957117438b0006b66bf2d72ef7 100644 (file)
@@ -27,5 +27,4 @@ set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb]
 runto "foo.adb:$bp_location"
 
 gdb_test "print Char_Enum_Type'('B')" "= 1 'B'"
-
-
+gdb_test "print pck.Global_Enum_Type'('Y')" "= 1 'Y'"
index 95914da2cfc674440d70997a170e92996a31c0e6..cf7fb7d339918d9959037959dda00d9c67d25b10 100644 (file)
@@ -18,6 +18,7 @@ with Pck; use Pck;
 procedure Foo is
    type Char_Enum_Type is ('A', 'B', 'C', 'D', 'E');
    Char : Char_Enum_Type := 'D';
+   Gchar : Global_Enum_Type := 'Z';
 begin
    Do_Nothing (Char'Address);  -- STOP
 end Foo;
index 5dd03889dee1e967917a493d924de48ff902dae1..f952e1c31c1eba973c4dbaa43aa44487f40fb213 100644 (file)
@@ -16,6 +16,7 @@
 with System;
 
 package Pck is
+   type Global_Enum_Type is ('X', 'Y', 'Z');
    procedure Do_Nothing (A : System.Address);
 end Pck;