[binutils-gdb] Handle missing array descriptor in ada_type_of_array
Tom Tromey via Gdb-cvs <[email protected]> Fri, 17 Jul 2026 16:27:32 +0000 (GMT)
| Newsgroups | gmane.comp.gdb.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dbe0be9e7a8bf= 7252489ddecc8013ebc476bf3c55 commit be0be9e7a8bf7252489ddecc8013ebc476bf3c55 Author: Tom Tromey <[email protected]> Date: Tue Jun 30 10:09:48 2026 -0600 Handle missing array descriptor in ada_type_of_array =20 The test case gdb.ada/mi_var_access.exp was failing with gnat-llvm. Debugging this, I found that the problem was that with gnat-llvm, the array descriptor would have a NULL pointer for the bounds when the array was invalidated. That is, examining the object in C mode: =20 (gdb) p a_string_access $1 =3D { P_ARRAY =3D 0x0, P_BOUNDS =3D 0x0 } =20 whereas when using GNAT we see: =20 (gdb) print a_string_access $1 =3D { P_ARRAY =3D 0x0, P_BOUNDS =3D 0x402750 } =20 This was causing ada_type_of_array to return nullptr; with that bubbling up to varobj and then MI as a "wrong" type in the MI output. =20 It seems to me that a null P_BOUNDS is reasonable; and that this case can be handled in ada_type_of_array by examining the type of P_BOUNDS without needing the bounds themselves. =20 The bound values are both set to 0 in this case, because experimentally this is what is done at runtime in the GNAT-generated code. Perhaps an explicitly empty array (1/0) would be better; I am not certain. Diff: --- gdb/ada-lang.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 85b08af8c06..e057e49b7fc 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -2177,20 +2177,35 @@ ada_type_of_array (struct value *arr, bool bounds) descriptor =3D desc_bounds (arr); /* In the extended access case, the bounds struct is "inline" so the pointer cannot be NULL. */ - if (ada_check_typedef (descriptor->type ())->code () =3D=3D TYPE_COD= E_PTR - && value_as_long (descriptor) =3D=3D 0) - return NULL; + const bool has_descriptor + =3D (ada_check_typedef (descriptor->type ())->code () !=3D TYPE_CODE_PTR + || value_as_long (descriptor) !=3D 0); while (arity > 0) { type_allocator alloc (arr->type ()); - struct value *low =3D desc_one_bound (descriptor, arity, 0); - struct value *high =3D desc_one_bound (descriptor, arity, 1); + LONGEST low =3D 0, high =3D 0; + type *bound_type; + + if (has_descriptor) + { + struct value *low_v =3D desc_one_bound (descriptor, arity, 0); + struct value *high_v =3D desc_one_bound (descriptor, arity, 1); + low =3D value_as_long (low_v); + high =3D value_as_long (high_v); + bound_type =3D low_v->type (); + } + else + { + /* We don't have the bounds, but we can still find the + type of each index. */ + bound_type + =3D desc_index_type (descriptor->type ()->target_type (), + arity); + } =20 arity -=3D 1; struct type *range_type - =3D create_static_range_type (alloc, low->type (), - value_as_long (low), - value_as_long (high)); + =3D create_static_range_type (alloc, bound_type, low, high); elt_type =3D create_array_type (alloc, elt_type, range_type); INIT_GNAT_SPECIFIC (elt_type); =20 @@ -2199,18 +2214,15 @@ ada_type_of_array (struct value *arr, bool bounds) /* We need to store the element packed bitsize, as well as recompute the array size, because it was previously computed based on the unpacked element size. */ - LONGEST lo =3D value_as_long (low); - LONGEST hi =3D value_as_long (high); - elt_type->field (0).set_bitsize (decode_packed_array_bitsize (arr->type ())); =20 /* If the array has no element, then the size is already zero, and does not need to be recomputed. */ - if (lo < hi) + if (low < high) { - int array_bitsize =3D - (hi - lo + 1) * elt_type->field (0).bitsize (); + int array_bitsize =3D ((high - low + 1) + * elt_type->field (0).bitsize ()); =20 elt_type->set_length ((array_bitsize + 7) / 8); }