[Ada] Crash with references to GNAT packed arrays handling

Consider the following declarations:

  type Packed_Array is array (Natural range <>) of Boolean;
  pragma Pack (Packed_Array);

  function Make (H, L : Natural) return Packed_Array is
  begin
     return (H .. L => False);
  end Make;

  A1 : Packed_Array := Make (1, 2);
  A2 : Packed_Array renames A1;

One possible DWARF translation for A2 is:

  <3><1e4>: Abbrev Number: 21 (DW_TAG_variable)
     <1e5>   DW_AT_name                 : a2
     <1ea>   DW_AT_type                 : <0x1d9>

  <3><1d9>: Abbrev Number: 22 (DW_TAG_const_type)
     <1da>   DW_AT_type                 : <0x1de>
  <3><1de>: Abbrev Number: 23 (DW_TAG_reference_type)
     <1e0>   DW_AT_type                 : <0x1a3>
  <3><1a3>: Abbrev Number: 17 (DW_TAG_array_type)
     <1a4>   DW_AT_name                 : foo__Ta1S___XP1
     <1a8>   DW_AT_GNAT_descriptive_type: <0x16b>

  <3><16b>: Abbrev Number: 6 (DW_TAG_typedef)
     <16c>   DW_AT_name                 : foo__Ta1S
     <172>   DW_AT_type                 : <0x176>
  <3><176>: Abbrev Number: 17 (DW_TAG_array_type)
     <177>   DW_AT_name                 : foo__Ta1S
     <17b>   DW_AT_GNAT_descriptive_type: <0x223>

Here, foo__Ta1S___XP1 is the type used for the code generation while
foo__Ta1S is the source-level type. Both form a valid GNAT encoding for
a packed array type.

Trying to print A2 (1) can make GDB crash. This is because A2 is defined
as a reference to a GNAT encoding for a packed array. When decoding
constrained packed arrays, the ada_coerce_ref subprogram follows
references and returns a fixed type from the target type, peeling
the GNAT encoding for packed arrays. The remaining code assumes that
the resulting type is still such an encoding while we only have
a standard GDB array type, hence the crash:

  arr = ada_coerce_ref (arr);
  [...]
  type = decode_constrained_packed_array_type (value_type (arr));

decode_constrained_packed_array_type assumes that its argument is
such an encoding. From its front comment:

  /* The array type encoded by TYPE, where
     ada_is_constrained_packed_array_type (TYPE).  */

This patch simply replaces the call to ada_coerce_ref with a call
to coerce_ref in order to avoid prematurely transforming
the packed array type as a side-effect. This way, the remaining code
will always work with a GNAT encoding.

gdb/ChangeLog:

	* ada-lang.c (decode_constrained_packed_array): Perform a
	minimal coercion for reference with coerce_ref instead of
	ada_coerce_ref.
This commit is contained in:
Pierre-Marie de Rodat 2014-03-14 14:55:42 +01:00 committed by Joel Brobecker
parent d4ccb5e05c
commit 11aa919a07
2 changed files with 14 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2014-03-17 Pierre-Marie de Rodat <derodat@adacore.com>
* ada-lang.c (decode_constrained_packed_array): Perform a
minimal coercion for reference with coerce_ref instead of
ada_coerce_ref.
2014-03-17 Tristan Gingold <gingold@adacore.com>
* solib-darwin.c (DYLD_VERSION_MAX): Increase value.

View File

@ -2250,14 +2250,14 @@ decode_constrained_packed_array (struct value *arr)
{
struct type *type;
arr = ada_coerce_ref (arr);
/* If our value is a pointer, then dererence it. Make sure that
this operation does not cause the target type to be fixed, as
this would indirectly cause this array to be decoded. The rest
of the routine assumes that the array hasn't been decoded yet,
so we use the basic "value_ind" routine to perform the dereferencing,
as opposed to using "ada_value_ind". */
/* If our value is a pointer, then dereference it. Likewise if
the value is a reference. Make sure that this operation does not
cause the target type to be fixed, as this would indirectly cause
this array to be decoded. The rest of the routine assumes that
the array hasn't been decoded yet, so we use the basic "coerce_ref"
and "value_ind" routines to perform the dereferencing, as opposed
to using "ada_coerce_ref" or "ada_value_ind". */
arr = coerce_ref (arr);
if (TYPE_CODE (ada_check_typedef (value_type (arr))) == TYPE_CODE_PTR)
arr = value_ind (arr);