Add dynamic_prop::is_constant

Message ID 20230427182906.325477-1-tromey@adacore.com
State New
Headers
Series Add dynamic_prop::is_constant |

Commit Message

Tom Tromey April 27, 2023, 6:29 p.m. UTC
  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.
---
 gdb/ada-lang.c                    |  6 +++---
 gdb/ada-tasks.c                   |  4 ++--
 gdb/compile/compile-c-types.c     |  2 +-
 gdb/compile/compile-cplus-types.c |  2 +-
 gdb/dwarf2/read.c                 | 10 +++++-----
 gdb/f-typeprint.c                 |  8 ++++----
 gdb/f-valprint.c                  |  4 ++--
 gdb/gdbtypes.c                    | 25 +++++++++++--------------
 gdb/gdbtypes.h                    |  5 +++++
 gdb/guile/scm-type.c              |  4 ++--
 gdb/m2-typeprint.c                |  2 +-
 gdb/p-typeprint.c                 |  2 +-
 gdb/python/py-type.c              |  4 ++--
 gdb/value.c                       | 10 +++++-----
 14 files changed, 45 insertions(+), 43 deletions(-)
  

Comments

Tom Tromey May 12, 2023, 6:30 p.m. UTC | #1
>>>>> "Tom" == Tom Tromey via Gdb-patches <gdb-patches@sourceware.org> writes:

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

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

Tom> Regression tested on x86-64 Fedora 36.

I'm checking this in.

Tom
  

Patch

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 3a9f554ce4c..586219c4298 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -673,7 +673,7 @@  ada_discrete_type_high_bound (struct type *type)
       {
 	const dynamic_prop &high = type->bounds ()->high;
 
-	if (high.kind () == PROP_CONST)
+	if (high.is_constant ())
 	  return high.const_val ();
 	else
 	  {
@@ -708,7 +708,7 @@  ada_discrete_type_low_bound (struct type *type)
       {
 	const dynamic_prop &low = type->bounds ()->low;
 
-	if (low.kind () == PROP_CONST)
+	if (low.is_constant ())
 	  return low.const_val ();
 	else
 	  {
@@ -11576,7 +11576,7 @@  ada_modulus (struct type *type)
 {
   const dynamic_prop &high = type->bounds ()->high;
 
-  if (high.kind () == PROP_CONST)
+  if (high.is_constant ())
     return (ULONGEST) high.const_val () + 1;
 
   /* If TYPE is unresolved, the high bound might be a location list.  Return
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index f107d4e4c28..8d0dec30485 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -943,8 +943,8 @@  ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data)
 	      && eltype->code () == TYPE_CODE_PTR)
 	    idxtype = check_typedef (type->index_type ());
 	  if (idxtype != NULL
-	      && idxtype->bounds ()->low.kind () != PROP_UNDEFINED
-	      && idxtype->bounds ()->high.kind () != PROP_UNDEFINED)
+	      && idxtype->bounds ()->low.is_constant ()
+	      && idxtype->bounds ()->high.is_constant ())
 	    {
 	      data->known_tasks_element = eltype;
 	      data->known_tasks_length =
diff --git a/gdb/compile/compile-c-types.c b/gdb/compile/compile-c-types.c
index f48eca2152a..4853c3f78b1 100644
--- a/gdb/compile/compile-c-types.c
+++ b/gdb/compile/compile-c-types.c
@@ -44,7 +44,7 @@  convert_array (compile_c_instance *context, struct type *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"
 				       " lower bound is not supported"));
   if (range->bounds ()->low.const_val () != 0)
diff --git a/gdb/compile/compile-cplus-types.c b/gdb/compile/compile-cplus-types.c
index 02cd3810b5d..206f4f658fb 100644
--- a/gdb/compile/compile-cplus-types.c
+++ b/gdb/compile/compile-cplus-types.c
@@ -455,7 +455,7 @@  compile_cplus_convert_array (compile_cplus_instance *instance,
   struct type *range = type->index_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"
 			" lower bound is not supported");
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 29a95cb8b2f..9ad826e3401 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -12414,8 +12414,8 @@  rewrite_array_type (struct type *type)
   if (new_target == nullptr)
     {
       /* Maybe we don't need to rewrite this array.  */
-      if (current_bounds->low.kind () == PROP_CONST
-	  && current_bounds->high.kind () == PROP_CONST)
+      if (current_bounds->low.is_constant ()
+	  && current_bounds->high.is_constant ())
 	return nullptr;
     }
 
@@ -15663,7 +15663,7 @@  read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
       if (attr_to_dynamic_prop (attr, die, cu, &high, base_type))
 	{
 	  /* 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);
 	  else
 	    high_bound_is_count = 1;
@@ -15705,11 +15705,11 @@  read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
       ULONGEST negative_mask
 	= -((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))
 	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))
 	high.set_const_val (high.const_val () | negative_mask);
     }
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 41862a2b353..882696c9394 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -176,11 +176,11 @@  f_language::f_type_print_varspec_suffix (struct type *type,
       else if (type_not_allocated (type))
 	print_rank_only = true;
       else if ((TYPE_ASSOCIATED_PROP (type)
-		&& PROP_CONST != TYPE_ASSOCIATED_PROP (type)->kind ())
+		&& !TYPE_ASSOCIATED_PROP (type)->is_constant ())
 	       || (TYPE_ALLOCATED_PROP (type)
-		   && PROP_CONST != TYPE_ALLOCATED_PROP (type)->kind ())
+		   && !TYPE_ALLOCATED_PROP (type)->is_constant ())
 	       || (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
 	     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
 	 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);
 
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 52bebae17fe..e3b45dd4a93 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -43,7 +43,7 @@  static void f77_get_dynamic_length_of_aggregate (struct type *);
 LONGEST
 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"));
 
   return type->bounds ()->low.const_val ();
@@ -52,7 +52,7 @@  f77_get_lowerbound (struct type *type)
 LONGEST
 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
 	 upper_bound == lower_bound so that we show at least 1 element.
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 6af59351b76..8a0a517a686 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -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
      range values will cause an unwanted sign extension.  So, we have
      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);
       /* Ada allows the declaration of range types whose upper bound is
 	 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
 	 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);
     }
 
@@ -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
      be initialized to the constant 0.  */
-  return (bounds->low.kind () == PROP_CONST
-	  && bounds->high.kind () == PROP_CONST
-	  && bounds->stride.kind () == PROP_CONST);
+  return (bounds->low.is_constant ()
+	  && bounds->high.is_constant ()
+	  && bounds->stride.is_constant ());
 }
 
 /* See gdbtypes.h.  */
@@ -1053,7 +1053,7 @@  get_discrete_low_bound (struct type *type)
     case TYPE_CODE_RANGE:
       {
 	/* 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 {};
 
 	LONGEST low = type->bounds ()->low.const_val ();
@@ -1124,7 +1124,7 @@  get_discrete_high_bound (struct type *type)
     case TYPE_CODE_RANGE:
       {
 	/* 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 {};
 
 	LONGEST high = type->bounds ()->high.const_val ();
@@ -1345,8 +1345,7 @@  create_array_type_with_stride (type_allocator &alloc,
 			       struct dynamic_prop *byte_stride_prop,
 			       unsigned int bit_stride)
 {
-  if (byte_stride_prop != NULL
-      && byte_stride_prop->kind () == PROP_CONST)
+  if (byte_stride_prop != nullptr && byte_stride_prop->is_constant ())
     {
       /* The byte stride is actually not dynamic.  Pretend we were
 	 called with bit_stride set instead of byte_stride_prop.
@@ -2037,7 +2036,7 @@  array_type_has_dynamic_stride (struct type *type)
 {
   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.  */
@@ -4381,8 +4380,7 @@  type_not_allocated (const struct type *type)
 {
   struct dynamic_prop *prop = TYPE_ALLOCATED_PROP (type);
 
-  return (prop != nullptr && prop->kind () == PROP_CONST
-	  && prop->const_val () == 0);
+  return prop != nullptr && prop->is_constant () && prop->const_val () == 0;
 }
 
 /* Associated status of type TYPE.  Return zero if type TYPE is associated.
@@ -4393,8 +4391,7 @@  type_not_associated (const struct type *type)
 {
   struct dynamic_prop *prop = TYPE_ASSOCIATED_PROP (type);
 
-  return (prop != nullptr && prop->kind () == PROP_CONST
-	  && prop->const_val () == 0);
+  return prop != nullptr && prop->is_constant () && prop->const_val () == 0;
 }
 
 /* rank_one_type helper for when PARM's type code is TYPE_CODE_PTR.  */
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index b5cccb784b2..4989f64dbd5 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -340,6 +340,11 @@  struct dynamic_prop
     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
   {
     gdb_assert (m_kind == PROP_LOCEXPR
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index 008e792cc34..033b800d8b0 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -827,12 +827,12 @@  gdbscm_type_range (SCM self)
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_STRING:
     case TYPE_CODE_RANGE:
-      if (type->bounds ()->low.kind () == PROP_CONST)
+      if (type->bounds ()->low.is_constant ())
 	low = type->bounds ()->low.const_val ();
       else
 	low = 0;
 
-      if (type->bounds ()->high.kind () == PROP_CONST)
+      if (type->bounds ()->high.is_constant ())
 	high = type->bounds ()->high.const_val ();
       else
 	high = 0;
diff --git a/gdb/m2-typeprint.c b/gdb/m2-typeprint.c
index 00a328852e9..2eea410bcd3 100644
--- a/gdb/m2-typeprint.c
+++ b/gdb/m2-typeprint.c
@@ -227,7 +227,7 @@  static void m2_array (struct type *type, struct ui_file *stream,
 {
   gdb_printf (stream, "ARRAY [");
   if (type->target_type ()->length () > 0
-      && type->bounds ()->high.kind () != PROP_UNDEFINED)
+      && type->bounds ()->high.is_constant ())
     {
       if (type->index_type () != 0)
 	{
diff --git a/gdb/p-typeprint.c b/gdb/p-typeprint.c
index 7458aa6c095..b6d3a120376 100644
--- a/gdb/p-typeprint.c
+++ b/gdb/p-typeprint.c
@@ -238,7 +238,7 @@  pascal_language::type_print_varspec_prefix (struct type *type,
 	gdb_printf (stream, "(");
       gdb_printf (stream, "array ");
       if (type->target_type ()->length () > 0
-	  && type->bounds ()->high.kind () != PROP_UNDEFINED)
+	  && type->bounds ()->high.is_constant ())
 	gdb_printf (stream, "[%s..%s] ",
 		    plongest (type->bounds ()->low.const_val ()),
 		    plongest (type->bounds ()->high.const_val ()));
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index b68ec8d2c92..300b3ebf9c1 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -609,12 +609,12 @@  typy_range (PyObject *self, PyObject *args)
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_STRING:
     case TYPE_CODE_RANGE:
-      if (type->bounds ()->low.kind () == PROP_CONST)
+      if (type->bounds ()->low.is_constant ())
 	low = type->bounds ()->low.const_val ();
       else
 	low = 0;
 
-      if (type->bounds ()->high.kind () == PROP_CONST)
+      if (type->bounds ()->high.is_constant ())
 	high = type->bounds ()->high.const_val ();
       else
 	high = 0;
diff --git a/gdb/value.c b/gdb/value.c
index eab1933b256..b2bcd03d80b 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1362,7 +1362,7 @@  value::address () const
     return m_parent->address () + m_offset;
   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 ());
     }
 
@@ -1612,14 +1612,14 @@  value::set_component_location (const struct value *whole)
      update the address of the COMPONENT.  */
   type = whole->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));
 
   /* Similarly, if the COMPONENT value has a dynamically resolved location
      property then update its address.  */
   type = this->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
 	 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);
       /* 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
 	 until we actual access the value.  */
       v = value::allocate_lazy (type);
@@ -3558,7 +3558,7 @@  value_from_contents_and_address (struct type *type,
   else
     v = value_from_contents (resolved_type, valaddr);
   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);
   v->set_lval (lval_memory);
   v->set_address (address);