[Ada] XA type is not redundant if the ranges' subtypes do not match
authorJoel Brobecker <brobecker@adacore.com>
Thu, 20 Nov 2014 08:10:41 +0000 (12:10 +0400)
committerJoel Brobecker <brobecker@adacore.com>
Thu, 20 Nov 2014 09:43:50 +0000 (13:43 +0400)
Jan noticed that gdb.ada/arrayidx.exp regressed after I applied
the following patch:

    commit 8908fca5772fcff9f7766158ba2aa59f5a2b1f68
    Author: Joel Brobecker <brobecker@adacore.com>
    Date:   Sat Sep 27 09:09:34 2014 -0700
    Subject: [Ada] Ignore __XA types when redundant.

What happens is that we're trying to print the value of
r_two_three, which is defined as follow:

   type Index is (One, Two, Three);
   type RTable is array (Index range Two .. Three) of Integer;
   R_Two_Three : RTable := (2, 3);

The expected output is:

    (gdb) p r_two_three
    $1 = (two => 2, 3)

But after the patch above was applied, with the program program
compiled using gcc-gnat-4.9.2-1.fc21.x86_64 (x86_64-linux),
the output becomes:

    (gdb) p r_two_three
    $1 = (2, 3)

(the name of the first bound is missing). The problem comes from
the fact that the compiler described the array's index type as
a plain base type, instead of as a subrange of the enumerated type.
More particularly, this is what gcc-gnat-4.9.2-1.fc21.x86_64
generated:

 <3><7ce>: Abbrev Number: 9 (DW_TAG_array_type)
    <7cf>   DW_AT_name        : (indirect string, offset: 0xc13): p__rtable
    [...]
    <7d7>   DW_AT_GNAT_descriptive_type: <0x98a>
    [...]
 <4><7df>: Abbrev Number: 8 (DW_TAG_subrange_type)
    <7e0>   DW_AT_type        : <0xa79>

where DIE 0xa79 is:

 <1><a79>: Abbrev Number: 2 (DW_TAG_base_type)
    <a7a>   DW_AT_byte_size   : 8
    <a7b>   DW_AT_encoding    : 7       (unsigned)
    <a7c>   DW_AT_name        : (indirect string, offset: 0xfc): sizetype

The actual array subrange type can be found in the array's
parallel XA type (the DW_AT_GNAT_descriptive_type).

The recent commit correctly found that that bounds taken from
the descriptive type are the same as bounds of our array's index
type. But it failed to notice that ignoring this descriptive
type would make us lose the actual array index type, making us
think that we're printing an array indexed by integers.

I hadn't seen that problem, because the compiler I used produced
debugging info where the array's index type is correctly described:

 <3><79f>: Abbrev Number: 10 (DW_TAG_array_type)
    <7a0>   DW_AT_name        : (indirect string, offset: 0xb3d): p__rtable
    [...]
 <4><7b0>: Abbrev Number: 8 (DW_TAG_subrange_type)
    <7b1>   DW_AT_type        : <0x9b2>
    <7b5>   DW_AT_upper_bound : 2

... where DIE 0x9b2 leads us to ...

 <3><9b2>: Abbrev Number: 9 (DW_TAG_subrange_type)
    [...]
    <9b8>   DW_AT_type        : <0x962>

 <2><962>: Abbrev Number: 22 (DW_TAG_enumeration_type)
    <963>   DW_AT_name        : (indirect string, offset: 0xb34): p__index
    [...]

This patch fixes the issue by also making sure that the subtype
of the original range type does match the subtype found in the
descriptive type.

gdb/ChangeLog:

        * ada-lang.c (ada_is_redundant_range_encoding): Return 0
        if the TYPE_CODE of range_type's base type does not match
        the TYPE_CODE of encoding_type's base type.

gdb/ChangeLog
gdb/ada-lang.c

index 5f58e6ca4ee0ae76121517882044dd73208f6f31..75b739e758abacc67034d65f60a9d23287866b53 100644 (file)
@@ -1,3 +1,9 @@
+2014-11-20  Joel Brobecker  <brobecker@adacore.com>
+
+       * ada-lang.c (ada_is_redundant_range_encoding): Return 0
+       if the TYPE_CODE of range_type's base type does not match
+       the TYPE_CODE of encoding_type's base type.
+
 2014-11-19  Joel Brobecker  <brobecker@adacore.com>
 
        * ada-lang.c (ada_unqualified_name): Return DECODED_NAME if
index e46ad8e2a057d37b2cdfa8fb3560b457a8a1541c..122aaf44d64fcf20adcc5d712beea692c5bc7287 100644 (file)
@@ -8334,6 +8334,17 @@ ada_is_redundant_range_encoding (struct type *range_type,
 
   gdb_assert (TYPE_CODE (range_type) == TYPE_CODE_RANGE);
 
+  if (TYPE_CODE (get_base_type (range_type))
+      != TYPE_CODE (get_base_type (encoding_type)))
+    {
+      /* The compiler probably used a simple base type to describe
+        the range type instead of the range's actual base type,
+        expecting us to get the real base type from the encoding
+        anyway.  In this situation, the encoding cannot be ignored
+        as redundant.  */
+      return 0;
+    }
+
   if (is_dynamic_type (range_type))
     return 0;
 
This page took 0.041957 seconds and 4 git commands to generate.