Fix cast of character to enum type in Ada

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.
This commit is contained in:
Tom Tromey 2019-05-03 12:18:26 -06:00
parent fcd60b848e
commit 222a8d2558
6 changed files with 23 additions and 3 deletions

View 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:

View 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;

View 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.

View 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'"

View 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;

View 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;