Add dynamic_prop::is_constant

I noticed many spots checking whether a dynamic property's kind is
PROP_CONST.  Some spots, I think, are doing a slightly incorrect check
-- checking for != PROP_UNDEFINED where == PROP_CONST is actually
required, the key thing being that const_val may only be called for
PROP_CONST properties.

This patch adds dynamic::is_constant and then updates these checks to
use it.

Regression tested on x86-64 Fedora 36.
This commit is contained in:
Tom Tromey 2023-04-19 09:40:20 -06:00
parent 14e8fded85
commit 9c0fb73485
14 changed files with 45 additions and 43 deletions

View file

@ -673,7 +673,7 @@ ada_discrete_type_high_bound (struct type *type)
{ {
const dynamic_prop &high = type->bounds ()->high; const dynamic_prop &high = type->bounds ()->high;
if (high.kind () == PROP_CONST) if (high.is_constant ())
return high.const_val (); return high.const_val ();
else else
{ {
@ -708,7 +708,7 @@ ada_discrete_type_low_bound (struct type *type)
{ {
const dynamic_prop &low = type->bounds ()->low; const dynamic_prop &low = type->bounds ()->low;
if (low.kind () == PROP_CONST) if (low.is_constant ())
return low.const_val (); return low.const_val ();
else else
{ {
@ -11576,7 +11576,7 @@ ada_modulus (struct type *type)
{ {
const dynamic_prop &high = type->bounds ()->high; const dynamic_prop &high = type->bounds ()->high;
if (high.kind () == PROP_CONST) if (high.is_constant ())
return (ULONGEST) high.const_val () + 1; return (ULONGEST) high.const_val () + 1;
/* If TYPE is unresolved, the high bound might be a location list. Return /* If TYPE is unresolved, the high bound might be a location list. Return

View file

@ -943,8 +943,8 @@ ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data)
&& eltype->code () == TYPE_CODE_PTR) && eltype->code () == TYPE_CODE_PTR)
idxtype = check_typedef (type->index_type ()); idxtype = check_typedef (type->index_type ());
if (idxtype != NULL if (idxtype != NULL
&& idxtype->bounds ()->low.kind () != PROP_UNDEFINED && idxtype->bounds ()->low.is_constant ()
&& idxtype->bounds ()->high.kind () != PROP_UNDEFINED) && idxtype->bounds ()->high.is_constant ())
{ {
data->known_tasks_element = eltype; data->known_tasks_element = eltype;
data->known_tasks_length = data->known_tasks_length =

View file

@ -44,7 +44,7 @@ convert_array (compile_c_instance *context, struct type *type)
element_type = context->convert_type (type->target_type ()); element_type = context->convert_type (type->target_type ());
if (range->bounds ()->low.kind () != PROP_CONST) if (!range->bounds ()->low.is_constant ())
return context->plugin ().error (_("array type with non-constant" return context->plugin ().error (_("array type with non-constant"
" lower bound is not supported")); " lower bound is not supported"));
if (range->bounds ()->low.const_val () != 0) if (range->bounds ()->low.const_val () != 0)

View file

@ -455,7 +455,7 @@ compile_cplus_convert_array (compile_cplus_instance *instance,
struct type *range = type->index_type (); struct type *range = type->index_type ();
gcc_type element_type = instance->convert_type (type->target_type ()); gcc_type element_type = instance->convert_type (type->target_type ());
if (range->bounds ()->low.kind () != PROP_CONST) if (!range->bounds ()->low.is_constant ())
{ {
const char *s = _("array type with non-constant" const char *s = _("array type with non-constant"
" lower bound is not supported"); " lower bound is not supported");

View file

@ -12424,8 +12424,8 @@ rewrite_array_type (struct type *type)
if (new_target == nullptr) if (new_target == nullptr)
{ {
/* Maybe we don't need to rewrite this array. */ /* Maybe we don't need to rewrite this array. */
if (current_bounds->low.kind () == PROP_CONST if (current_bounds->low.is_constant ()
&& current_bounds->high.kind () == PROP_CONST) && current_bounds->high.is_constant ())
return nullptr; return nullptr;
} }
@ -15673,7 +15673,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
if (attr_to_dynamic_prop (attr, die, cu, &high, base_type)) if (attr_to_dynamic_prop (attr, die, cu, &high, base_type))
{ {
/* If bounds are constant do the final calculation here. */ /* If bounds are constant do the final calculation here. */
if (low.kind () == PROP_CONST && high.kind () == PROP_CONST) if (low.is_constant () && high.is_constant ())
high.set_const_val (low.const_val () + high.const_val () - 1); high.set_const_val (low.const_val () + high.const_val () - 1);
else else
high_bound_is_count = 1; high_bound_is_count = 1;
@ -15715,11 +15715,11 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
ULONGEST negative_mask ULONGEST negative_mask
= -((ULONGEST) 1 << (base_type->length () * TARGET_CHAR_BIT - 1)); = -((ULONGEST) 1 << (base_type->length () * TARGET_CHAR_BIT - 1));
if (low.kind () == PROP_CONST if (low.is_constant ()
&& !base_type->is_unsigned () && (low.const_val () & negative_mask)) && !base_type->is_unsigned () && (low.const_val () & negative_mask))
low.set_const_val (low.const_val () | negative_mask); low.set_const_val (low.const_val () | negative_mask);
if (high.kind () == PROP_CONST if (high.is_constant ()
&& !base_type->is_unsigned () && (high.const_val () & negative_mask)) && !base_type->is_unsigned () && (high.const_val () & negative_mask))
high.set_const_val (high.const_val () | negative_mask); high.set_const_val (high.const_val () | negative_mask);
} }

View file

@ -176,11 +176,11 @@ f_language::f_type_print_varspec_suffix (struct type *type,
else if (type_not_allocated (type)) else if (type_not_allocated (type))
print_rank_only = true; print_rank_only = true;
else if ((TYPE_ASSOCIATED_PROP (type) else if ((TYPE_ASSOCIATED_PROP (type)
&& PROP_CONST != TYPE_ASSOCIATED_PROP (type)->kind ()) && !TYPE_ASSOCIATED_PROP (type)->is_constant ())
|| (TYPE_ALLOCATED_PROP (type) || (TYPE_ALLOCATED_PROP (type)
&& PROP_CONST != TYPE_ALLOCATED_PROP (type)->kind ()) && !TYPE_ALLOCATED_PROP (type)->is_constant ())
|| (TYPE_DATA_LOCATION (type) || (TYPE_DATA_LOCATION (type)
&& PROP_CONST != TYPE_DATA_LOCATION (type)->kind ())) && !TYPE_DATA_LOCATION (type)->is_constant ()))
{ {
/* This case exist when we ptype a typename which has the dynamic /* This case exist when we ptype a typename which has the dynamic
properties but cannot be resolved as there is no object. */ properties but cannot be resolved as there is no object. */
@ -395,7 +395,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
asked to print the type of a value with a dynamic type then the asked to print the type of a value with a dynamic type then the
bounds will not have been resolved. */ bounds will not have been resolved. */
if (type->bounds ()->high.kind () == PROP_CONST) if (type->bounds ()->high.is_constant ())
{ {
LONGEST upper_bound = f77_get_upperbound (type); LONGEST upper_bound = f77_get_upperbound (type);

View file

@ -43,7 +43,7 @@ static void f77_get_dynamic_length_of_aggregate (struct type *);
LONGEST LONGEST
f77_get_lowerbound (struct type *type) f77_get_lowerbound (struct type *type)
{ {
if (type->bounds ()->low.kind () != PROP_CONST) if (!type->bounds ()->low.is_constant ())
error (_("Lower bound may not be '*' in F77")); error (_("Lower bound may not be '*' in F77"));
return type->bounds ()->low.const_val (); return type->bounds ()->low.const_val ();
@ -52,7 +52,7 @@ f77_get_lowerbound (struct type *type)
LONGEST LONGEST
f77_get_upperbound (struct type *type) f77_get_upperbound (struct type *type)
{ {
if (type->bounds ()->high.kind () != PROP_CONST) if (!type->bounds ()->high.is_constant ())
{ {
/* We have an assumed size array on our hands. Assume that /* We have an assumed size array on our hands. Assume that
upper_bound == lower_bound so that we show at least 1 element. upper_bound == lower_bound so that we show at least 1 element.

View file

@ -974,14 +974,14 @@ create_range_type (type_allocator &alloc, struct type *index_type,
case, if we copy the underlying type's sign, then reading some case, if we copy the underlying type's sign, then reading some
range values will cause an unwanted sign extension. So, we have range values will cause an unwanted sign extension. So, we have
some heuristics here instead. */ some heuristics here instead. */
else if (low_bound->kind () == PROP_CONST && low_bound->const_val () >= 0) else if (low_bound->is_constant () && low_bound->const_val () >= 0)
{ {
result_type->set_is_unsigned (true); result_type->set_is_unsigned (true);
/* Ada allows the declaration of range types whose upper bound is /* Ada allows the declaration of range types whose upper bound is
less than the lower bound, so checking the lower bound is not less than the lower bound, so checking the lower bound is not
enough. Make sure we do not mark a range type whose upper bound enough. Make sure we do not mark a range type whose upper bound
is negative as unsigned. */ is negative as unsigned. */
if (high_bound->kind () == PROP_CONST && high_bound->const_val () < 0) if (high_bound->is_constant () && high_bound->const_val () < 0)
result_type->set_is_unsigned (false); result_type->set_is_unsigned (false);
} }
@ -1037,9 +1037,9 @@ has_static_range (const struct range_bounds *bounds)
{ {
/* If the range doesn't have a defined stride then its stride field will /* If the range doesn't have a defined stride then its stride field will
be initialized to the constant 0. */ be initialized to the constant 0. */
return (bounds->low.kind () == PROP_CONST return (bounds->low.is_constant ()
&& bounds->high.kind () == PROP_CONST && bounds->high.is_constant ()
&& bounds->stride.kind () == PROP_CONST); && bounds->stride.is_constant ());
} }
/* See gdbtypes.h. */ /* See gdbtypes.h. */
@ -1053,7 +1053,7 @@ get_discrete_low_bound (struct type *type)
case TYPE_CODE_RANGE: case TYPE_CODE_RANGE:
{ {
/* This function only works for ranges with a constant low bound. */ /* This function only works for ranges with a constant low bound. */
if (type->bounds ()->low.kind () != PROP_CONST) if (!type->bounds ()->low.is_constant ())
return {}; return {};
LONGEST low = type->bounds ()->low.const_val (); LONGEST low = type->bounds ()->low.const_val ();
@ -1120,7 +1120,7 @@ get_discrete_high_bound (struct type *type)
case TYPE_CODE_RANGE: case TYPE_CODE_RANGE:
{ {
/* This function only works for ranges with a constant high bound. */ /* This function only works for ranges with a constant high bound. */
if (type->bounds ()->high.kind () != PROP_CONST) if (!type->bounds ()->high.is_constant ())
return {}; return {};
LONGEST high = type->bounds ()->high.const_val (); LONGEST high = type->bounds ()->high.const_val ();
@ -1341,8 +1341,7 @@ create_array_type_with_stride (type_allocator &alloc,
struct dynamic_prop *byte_stride_prop, struct dynamic_prop *byte_stride_prop,
unsigned int bit_stride) unsigned int bit_stride)
{ {
if (byte_stride_prop != NULL if (byte_stride_prop != nullptr && byte_stride_prop->is_constant ())
&& byte_stride_prop->kind () == PROP_CONST)
{ {
/* The byte stride is actually not dynamic. Pretend we were /* The byte stride is actually not dynamic. Pretend we were
called with bit_stride set instead of byte_stride_prop. called with bit_stride set instead of byte_stride_prop.
@ -2033,7 +2032,7 @@ array_type_has_dynamic_stride (struct type *type)
{ {
struct dynamic_prop *prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE); struct dynamic_prop *prop = type->dyn_prop (DYN_PROP_BYTE_STRIDE);
return (prop != NULL && prop->kind () != PROP_CONST); return prop != nullptr && prop->is_constant ();
} }
/* Worker for is_dynamic_type. */ /* Worker for is_dynamic_type. */
@ -4377,8 +4376,7 @@ type_not_allocated (const struct type *type)
{ {
struct dynamic_prop *prop = TYPE_ALLOCATED_PROP (type); struct dynamic_prop *prop = TYPE_ALLOCATED_PROP (type);
return (prop != nullptr && prop->kind () == PROP_CONST return prop != nullptr && prop->is_constant () && prop->const_val () == 0;
&& prop->const_val () == 0);
} }
/* Associated status of type TYPE. Return zero if type TYPE is associated. /* Associated status of type TYPE. Return zero if type TYPE is associated.
@ -4389,8 +4387,7 @@ type_not_associated (const struct type *type)
{ {
struct dynamic_prop *prop = TYPE_ASSOCIATED_PROP (type); struct dynamic_prop *prop = TYPE_ASSOCIATED_PROP (type);
return (prop != nullptr && prop->kind () == PROP_CONST return prop != nullptr && prop->is_constant () && prop->const_val () == 0;
&& prop->const_val () == 0);
} }
/* rank_one_type helper for when PARM's type code is TYPE_CODE_PTR. */ /* rank_one_type helper for when PARM's type code is TYPE_CODE_PTR. */

View file

@ -340,6 +340,11 @@ struct dynamic_prop
m_data.const_val = const_val; m_data.const_val = const_val;
} }
/* Return true if this property has a constant value, false
otherwise. */
bool is_constant () const
{ return m_kind == PROP_CONST; }
const dwarf2_property_baton *baton () const const dwarf2_property_baton *baton () const
{ {
gdb_assert (m_kind == PROP_LOCEXPR gdb_assert (m_kind == PROP_LOCEXPR

View file

@ -827,12 +827,12 @@ gdbscm_type_range (SCM self)
case TYPE_CODE_ARRAY: case TYPE_CODE_ARRAY:
case TYPE_CODE_STRING: case TYPE_CODE_STRING:
case TYPE_CODE_RANGE: case TYPE_CODE_RANGE:
if (type->bounds ()->low.kind () == PROP_CONST) if (type->bounds ()->low.is_constant ())
low = type->bounds ()->low.const_val (); low = type->bounds ()->low.const_val ();
else else
low = 0; low = 0;
if (type->bounds ()->high.kind () == PROP_CONST) if (type->bounds ()->high.is_constant ())
high = type->bounds ()->high.const_val (); high = type->bounds ()->high.const_val ();
else else
high = 0; high = 0;

View file

@ -227,7 +227,7 @@ static void m2_array (struct type *type, struct ui_file *stream,
{ {
gdb_printf (stream, "ARRAY ["); gdb_printf (stream, "ARRAY [");
if (type->target_type ()->length () > 0 if (type->target_type ()->length () > 0
&& type->bounds ()->high.kind () != PROP_UNDEFINED) && type->bounds ()->high.is_constant ())
{ {
if (type->index_type () != 0) if (type->index_type () != 0)
{ {

View file

@ -238,7 +238,7 @@ pascal_language::type_print_varspec_prefix (struct type *type,
gdb_printf (stream, "("); gdb_printf (stream, "(");
gdb_printf (stream, "array "); gdb_printf (stream, "array ");
if (type->target_type ()->length () > 0 if (type->target_type ()->length () > 0
&& type->bounds ()->high.kind () != PROP_UNDEFINED) && type->bounds ()->high.is_constant ())
gdb_printf (stream, "[%s..%s] ", gdb_printf (stream, "[%s..%s] ",
plongest (type->bounds ()->low.const_val ()), plongest (type->bounds ()->low.const_val ()),
plongest (type->bounds ()->high.const_val ())); plongest (type->bounds ()->high.const_val ()));

View file

@ -609,12 +609,12 @@ typy_range (PyObject *self, PyObject *args)
case TYPE_CODE_ARRAY: case TYPE_CODE_ARRAY:
case TYPE_CODE_STRING: case TYPE_CODE_STRING:
case TYPE_CODE_RANGE: case TYPE_CODE_RANGE:
if (type->bounds ()->low.kind () == PROP_CONST) if (type->bounds ()->low.is_constant ())
low = type->bounds ()->low.const_val (); low = type->bounds ()->low.const_val ();
else else
low = 0; low = 0;
if (type->bounds ()->high.kind () == PROP_CONST) if (type->bounds ()->high.is_constant ())
high = type->bounds ()->high.const_val (); high = type->bounds ()->high.const_val ();
else else
high = 0; high = 0;

View file

@ -1362,7 +1362,7 @@ value::address () const
return m_parent->address () + m_offset; return m_parent->address () + m_offset;
if (NULL != TYPE_DATA_LOCATION (type ())) if (NULL != TYPE_DATA_LOCATION (type ()))
{ {
gdb_assert (PROP_CONST == TYPE_DATA_LOCATION_KIND (type ())); gdb_assert (TYPE_DATA_LOCATION (type ())->is_constant ());
return TYPE_DATA_LOCATION_ADDR (type ()); return TYPE_DATA_LOCATION_ADDR (type ());
} }
@ -1612,14 +1612,14 @@ value::set_component_location (const struct value *whole)
update the address of the COMPONENT. */ update the address of the COMPONENT. */
type = whole->type (); type = whole->type ();
if (NULL != TYPE_DATA_LOCATION (type) if (NULL != TYPE_DATA_LOCATION (type)
&& TYPE_DATA_LOCATION_KIND (type) == PROP_CONST) && TYPE_DATA_LOCATION (type)->is_constant ())
set_address (TYPE_DATA_LOCATION_ADDR (type)); set_address (TYPE_DATA_LOCATION_ADDR (type));
/* Similarly, if the COMPONENT value has a dynamically resolved location /* Similarly, if the COMPONENT value has a dynamically resolved location
property then update its address. */ property then update its address. */
type = this->type (); type = this->type ();
if (NULL != TYPE_DATA_LOCATION (type) if (NULL != TYPE_DATA_LOCATION (type)
&& TYPE_DATA_LOCATION_KIND (type) == PROP_CONST) && TYPE_DATA_LOCATION (type)->is_constant ())
{ {
/* If the COMPONENT has a dynamic location, and is an /* If the COMPONENT has a dynamic location, and is an
lval_internalvar_component, then we change it to a lval_memory. lval_internalvar_component, then we change it to a lval_memory.
@ -3005,7 +3005,7 @@ value::primitive_field (LONGEST offset, int fieldno, struct type *arg_type)
gdb_assert (0 == offset); gdb_assert (0 == offset);
/* We expect an already resolved data location. */ /* We expect an already resolved data location. */
gdb_assert (PROP_CONST == TYPE_DATA_LOCATION_KIND (type)); gdb_assert (TYPE_DATA_LOCATION (type)->is_constant ());
/* For dynamic data types defer memory allocation /* For dynamic data types defer memory allocation
until we actual access the value. */ until we actual access the value. */
v = value::allocate_lazy (type); v = value::allocate_lazy (type);
@ -3558,7 +3558,7 @@ value_from_contents_and_address (struct type *type,
else else
v = value_from_contents (resolved_type, valaddr); v = value_from_contents (resolved_type, valaddr);
if (TYPE_DATA_LOCATION (resolved_type_no_typedef) != NULL if (TYPE_DATA_LOCATION (resolved_type_no_typedef) != NULL
&& TYPE_DATA_LOCATION_KIND (resolved_type_no_typedef) == PROP_CONST) && TYPE_DATA_LOCATION (resolved_type_no_typedef)->is_constant ())
address = TYPE_DATA_LOCATION_ADDR (resolved_type_no_typedef); address = TYPE_DATA_LOCATION_ADDR (resolved_type_no_typedef);
v->set_lval (lval_memory); v->set_lval (lval_memory);
v->set_address (address); v->set_address (address);