[1/2] Fix bugs in 'val and 'pos with range types

Message ID 20200519171808.2637-2-tromey@adacore.com
State New
Headers show
Series
  • Fix some Ada enum bugs
Related show

Commit Message

Tom Tromey May 19, 2020, 5:18 p.m.
In Ada, the 'val and 'pos attributes can be used to map from an
enumeration constant to its position in the enum and vice versa.
These operators did not work properly when the type in question was a
subrange of an enum type with "holes".

gdb/ChangeLog
2020-05-19  Tom Tromey  <tromey@adacore.com>

	* ada-lang.c (value_val_atr): Handle TYPE_CODE_RANGE.
	* gdbtypes.c (discrete_position): Handle TYPE_CODE_RANGE.

gdb/testsuite/ChangeLog
2020-05-19  Tom Tromey  <tromey@adacore.com>

	* gdb.ada/arr_acc_idx_w_gap.exp: Add enum subrange tests.
	* gdb.ada/arr_acc_idx_w_gap/enum_with_gap.ads (Enum_Subrange): New
	type.
	* gdb.ada/arr_acc_idx_w_gap/enum_with_gap_main.adb (V): New
	variable.
---
 gdb/ChangeLog                                             | 5 +++++
 gdb/ada-lang.c                                            | 3 +++
 gdb/gdbtypes.c                                            | 3 +++
 gdb/testsuite/ChangeLog                                   | 8 ++++++++
 gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp               | 4 ++++
 gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap.ads | 6 ++++--
 .../gdb.ada/arr_acc_idx_w_gap/enum_with_gap_main.adb      | 1 +
 7 files changed, 28 insertions(+), 2 deletions(-)

-- 
2.21.1

Patch

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 825549d86e9..d8489889c85 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -9150,6 +9150,9 @@  value_val_atr (struct type *type, struct value *arg)
   if (!integer_type_p (value_type (arg)))
     error (_("'VAL requires integral argument"));
 
+  if (type->code () == TYPE_CODE_RANGE)
+    type = TYPE_TARGET_TYPE (type);
+
   if (type->code () == TYPE_CODE_ENUM)
     {
       long pos = value_as_long (arg);
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 68d4c0c4a24..83490eaf8ba 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1155,6 +1155,9 @@  get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
 int
 discrete_position (struct type *type, LONGEST val, LONGEST *pos)
 {
+  if (type->code () == TYPE_CODE_RANGE)
+    type = TYPE_TARGET_TYPE (type);
+
   if (type->code () == TYPE_CODE_ENUM)
     {
       int i;
diff --git a/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp b/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp
index fd7ac44cb05..c08070ea53c 100644
--- a/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp
+++ b/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap.exp
@@ -53,3 +53,7 @@  gdb_test "print indexed_by_enum(lit2..lit4)" \
          " = \\(lit2 => 43, 42, 41\\)"
 gdb_test "print s(2..4)" \
          " = \"ell\""
+
+gdb_test "print v" " = lit3"
+gdb_test "print enum_subrange'pos(v)" " = 3"
+gdb_test "print enum_subrange'val(3)" " = lit3"
diff --git a/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap.ads b/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap.ads
index 6e073e88a49..719380077e1 100644
--- a/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap.ads
+++ b/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap.ads
@@ -34,14 +34,16 @@  package Enum_With_Gap is
      );
    for Enum_With_Gaps'size use 16;
 
+   type Enum_Subrange is new Enum_With_Gaps range Lit1 .. Lit3;
+
    type MyWord is range 0 .. 16#FFFF# ;
    for MyWord'Size use 16;
 
    type AR is array (Enum_With_Gaps range <>) of MyWord;
    type AR_Access is access AR;
-   
+
    type String_Access is access String;
-   
+
    procedure Do_Nothing (E : AR_Access);
    procedure Do_Nothing (E : String_Access);
 
diff --git a/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap_main.adb b/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap_main.adb
index da37dd7d5ec..752b8837980 100644
--- a/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap_main.adb
+++ b/gdb/testsuite/gdb.ada/arr_acc_idx_w_gap/enum_with_gap_main.adb
@@ -19,6 +19,7 @@  procedure Enum_With_Gap_Main is
    Indexed_By_Enum : AR_Access :=
      new AR'(LIT1 => 1,  LIT2 => 43, LIT3 => 42, LIT4 => 41);
    S : String_Access := new String'("Hello!");
+   V : Enum_Subrange := LIT3;
 begin
    Do_Nothing (Indexed_By_Enum); --  BREAK
    Do_Nothing (S);