mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-05 21:50:21 +08:00
[Ada] Allow assignment to wide string.
Given the following variable declaration... Www : Wide_String := "12345"; ... this patch allows the following assignment to work: (gdb) set variable www := "qwert" Without this patch, the debugger rejects the assignment because the size of the array elements are different: (gdb) set www := "asdfg" Incompatible types in assignment (on the lhs, we have an array of 2-bytes elements, and on the rhs, we have a standard 1-byte string). gdb/ChangeLog: * ada-lang.c (ada_same_array_size_p): New function. (ada_promote_array_of_integrals): New function. (coerce_for_assign): Add handling of arrays where the elements are integrals of a smaller size than the size of the target array element type. gdb/testsuite/ChangeLog: * gdb.ada/set_wstr: New testcase.
This commit is contained in:
@ -8629,6 +8629,72 @@ cast_from_fixed (struct type *type, struct value *arg)
|
||||
return value_from_double (type, val);
|
||||
}
|
||||
|
||||
/* Given two array types T1 and T2, return nonzero iff both arrays
|
||||
contain the same number of elements. */
|
||||
|
||||
static int
|
||||
ada_same_array_size_p (struct type *t1, struct type *t2)
|
||||
{
|
||||
LONGEST lo1, hi1, lo2, hi2;
|
||||
|
||||
/* Get the array bounds in order to verify that the size of
|
||||
the two arrays match. */
|
||||
if (!get_array_bounds (t1, &lo1, &hi1)
|
||||
|| !get_array_bounds (t2, &lo2, &hi2))
|
||||
error (_("unable to determine array bounds"));
|
||||
|
||||
/* To make things easier for size comparison, normalize a bit
|
||||
the case of empty arrays by making sure that the difference
|
||||
between upper bound and lower bound is always -1. */
|
||||
if (lo1 > hi1)
|
||||
hi1 = lo1 - 1;
|
||||
if (lo2 > hi2)
|
||||
hi2 = lo2 - 1;
|
||||
|
||||
return (hi1 - lo1 == hi2 - lo2);
|
||||
}
|
||||
|
||||
/* Assuming that VAL is an array of integrals, and TYPE represents
|
||||
an array with the same number of elements, but with wider integral
|
||||
elements, return an array "casted" to TYPE. In practice, this
|
||||
means that the returned array is built by casting each element
|
||||
of the original array into TYPE's (wider) element type. */
|
||||
|
||||
static struct value *
|
||||
ada_promote_array_of_integrals (struct type *type, struct value *val)
|
||||
{
|
||||
struct type *elt_type = TYPE_TARGET_TYPE (type);
|
||||
LONGEST lo, hi;
|
||||
struct value *res;
|
||||
LONGEST i;
|
||||
|
||||
/* Verify that both val and type are arrays of scalars, and
|
||||
that the size of val's elements is smaller than the size
|
||||
of type's element. */
|
||||
gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
|
||||
gdb_assert (is_integral_type (TYPE_TARGET_TYPE (type)));
|
||||
gdb_assert (TYPE_CODE (value_type (val)) == TYPE_CODE_ARRAY);
|
||||
gdb_assert (is_integral_type (TYPE_TARGET_TYPE (value_type (val))));
|
||||
gdb_assert (TYPE_LENGTH (TYPE_TARGET_TYPE (type))
|
||||
> TYPE_LENGTH (TYPE_TARGET_TYPE (value_type (val))));
|
||||
|
||||
if (!get_array_bounds (type, &lo, &hi))
|
||||
error (_("unable to determine array bounds"));
|
||||
|
||||
res = allocate_value (type);
|
||||
|
||||
/* Promote each array element. */
|
||||
for (i = 0; i < hi - lo + 1; i++)
|
||||
{
|
||||
struct value *elt = value_cast (elt_type, value_subscript (val, lo + i));
|
||||
|
||||
memcpy (value_contents_writeable (res) + (i * TYPE_LENGTH (elt_type)),
|
||||
value_contents_all (elt), TYPE_LENGTH (elt_type));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Coerce VAL as necessary for assignment to an lval of type TYPE, and
|
||||
return the converted value. */
|
||||
|
||||
@ -8653,9 +8719,21 @@ coerce_for_assign (struct type *type, struct value *val)
|
||||
if (TYPE_CODE (type2) == TYPE_CODE_ARRAY
|
||||
&& TYPE_CODE (type) == TYPE_CODE_ARRAY)
|
||||
{
|
||||
if (TYPE_LENGTH (type2) != TYPE_LENGTH (type)
|
||||
|| TYPE_LENGTH (TYPE_TARGET_TYPE (type2))
|
||||
!= TYPE_LENGTH (TYPE_TARGET_TYPE (type2)))
|
||||
if (!ada_same_array_size_p (type, type2))
|
||||
error (_("cannot assign arrays of different length"));
|
||||
|
||||
if (is_integral_type (TYPE_TARGET_TYPE (type))
|
||||
&& is_integral_type (TYPE_TARGET_TYPE (type2))
|
||||
&& TYPE_LENGTH (TYPE_TARGET_TYPE (type2))
|
||||
< TYPE_LENGTH (TYPE_TARGET_TYPE (type)))
|
||||
{
|
||||
/* Allow implicit promotion of the array elements to
|
||||
a wider type. */
|
||||
return ada_promote_array_of_integrals (type, val);
|
||||
}
|
||||
|
||||
if (TYPE_LENGTH (TYPE_TARGET_TYPE (type2))
|
||||
!= TYPE_LENGTH (TYPE_TARGET_TYPE (type)))
|
||||
error (_("Incompatible types in assignment"));
|
||||
deprecated_set_value_type (val, type);
|
||||
}
|
||||
|
Reference in New Issue
Block a user