From: Pierre-Marie de Rodat Date: Fri, 14 Mar 2014 13:55:42 +0000 (+0100) Subject: [Ada] Crash with references to GNAT packed arrays handling X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=11aa919a07114ba99a99a7dcd43079440bbe5161;p=binutils-gdb.git [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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5b659d26cd9..4e62f0c757d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2014-03-17 Pierre-Marie de Rodat + + * 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 * solib-darwin.c (DYLD_VERSION_MAX): Increase value. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 31aa38088c0..38df182e21f 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -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);