mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-01 14:03:56 +08:00
gdb: make get_discrete_bounds check for non-constant range bounds
The next patch adds getters to the `dynamic_prop` structure. These getters validate that the accessed data matches the property kind (for example, to access the `const_val` field, the property must be of kind `PROP_CONST`). It found one instance where we are accessing the `const_val` data of a property that has the undefined kind. This happens in function `get_discrete_bounds`, and is exposed by test gdb.base/ptype.exp, amongst others. Without this patch, we would get: $ ./gdb -q -nx --data-directory=data-directory testsuite/outputs/gdb.base/ptype/ptype -ex "ptype t_char_array" Reading symbols from testsuite/outputs/gdb.base/ptype/ptype... type = char [ /home/smarchi/src/binutils-gdb/gdb/gdbtypes.h:526: internal-error: LONGEST dynamic_prop::const_val() const: Assertion `m_kind == PROP_CONST' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) The `get_discrete_bounds` function returns the bounds of a type (not only range types). For range types, it naturally uses the bound properties that are intrinsic to the range type. It accesses these properties using TYPE_LOW_BOUND and TYPE_HIGH_BOUND, which assume the properties are defined and have constant values. This is sometimes not the case, and the passed range type (as in the example above) has an undefined high/upper bound. Given its current interface (returning two LONGEST values for low and high), `get_discrete_bounds` can't really work if the range type's bounds are not both defined and both constant values. This patch changes the function to return -1 (failure to get the bounds) if any of the range type's bounds is not a constant value. It is sufficient to fix the issue and it seems to keep the callers happy, at least according to the testsuite. A bit in `get_array_bounds` could be removed, since `get_discrete_bounds` no longer returns 1 if a bound is undefined. gdb/ChangeLog: * gdbtypes.c (get_discrete_bounds): Return failure if the range type's bounds are not both defined and constant values. (get_array_bounds): Update comment. Remove undefined bound check. Change-Id: I047a3beee2c1e275f888cfc4778228339922bde9
This commit is contained in:
parent
599088e3ff
commit
7c6f271296
@ -1,3 +1,10 @@
|
||||
2020-07-12 Simon Marchi <simon.marchi@efficios.com>
|
||||
|
||||
* gdbtypes.c (get_discrete_bounds): Return failure if
|
||||
the range type's bounds are not both defined and constant
|
||||
values.
|
||||
(get_array_bounds): Update comment. Remove undefined bound check.
|
||||
|
||||
2020-07-12 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
* gdbtypes.h (TYPE_RANGE_DATA): Remove. Update callers to use
|
||||
|
@ -1028,8 +1028,11 @@ has_static_range (const struct range_bounds *bounds)
|
||||
|
||||
|
||||
/* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
|
||||
TYPE. Return 1 if type is a range type, 0 if it is discrete (and
|
||||
bounds will fit in LONGEST), or -1 otherwise. */
|
||||
TYPE.
|
||||
|
||||
Return 1 if type is a range type with two defined, constant bounds.
|
||||
Else, return 0 if it is discrete (and bounds will fit in LONGEST).
|
||||
Else, return -1. */
|
||||
|
||||
int
|
||||
get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
|
||||
@ -1038,8 +1041,15 @@ get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
|
||||
switch (type->code ())
|
||||
{
|
||||
case TYPE_CODE_RANGE:
|
||||
/* This function currently only works for ranges with two defined,
|
||||
constant bounds. */
|
||||
if (type->bounds ()->low.kind () != PROP_CONST
|
||||
|| type->bounds ()->high.kind () != PROP_CONST)
|
||||
return -1;
|
||||
|
||||
*lowp = TYPE_LOW_BOUND (type);
|
||||
*highp = TYPE_HIGH_BOUND (type);
|
||||
|
||||
if (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ENUM)
|
||||
{
|
||||
if (!discrete_position (TYPE_TARGET_TYPE (type), *lowp, lowp)
|
||||
@ -1107,14 +1117,7 @@ get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
|
||||
Save the high bound into HIGH_BOUND if not NULL.
|
||||
|
||||
Return 1 if the operation was successful. Return zero otherwise,
|
||||
in which case the values of LOW_BOUND and HIGH_BOUNDS are unmodified.
|
||||
|
||||
We now simply use get_discrete_bounds call to get the values
|
||||
of the low and high bounds.
|
||||
get_discrete_bounds can return three values:
|
||||
1, meaning that index is a range,
|
||||
0, meaning that index is a discrete type,
|
||||
or -1 for failure. */
|
||||
in which case the values of LOW_BOUND and HIGH_BOUNDS are unmodified. */
|
||||
|
||||
int
|
||||
get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
|
||||
@ -1131,12 +1134,6 @@ get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
|
||||
if (res == -1)
|
||||
return 0;
|
||||
|
||||
/* Check if the array bounds are undefined. */
|
||||
if (res == 1
|
||||
&& ((low_bound && TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED (type))
|
||||
|| (high_bound && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))))
|
||||
return 0;
|
||||
|
||||
if (low_bound)
|
||||
*low_bound = low;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user