Allow lazy 'zero' value
authorTom Tromey <tromey@adacore.com>
Mon, 13 Sep 2021 18:31:20 +0000 (12:31 -0600)
committerTom Tromey <tromey@adacore.com>
Tue, 5 Oct 2021 18:34:55 +0000 (12:34 -0600)
This changes value_zero to create a lazy value.  In many cases,
value_zero is called in expression evaluation to wrap a type in a
non-eval context.  It seems senseless to allocate a buffer in these
cases.

A new 'is_zero' flag is added so we can preserve the existing
assertions in value_fetch_lazy.

A subsequent patch will add a test where creating a zero value would
fail, due to the variable size check.  However, the contents of this
value are never needed, and so creating a lazy value avoids the error
case.

gdb/valops.c
gdb/value.c

index a6c3632fe1851d06a89ac5ee568d730cef9c07f2..f65479b8117d71b993d27e13d277aecc74ffde53 100644 (file)
@@ -935,17 +935,6 @@ value_dynamic_cast (struct type *type, struct value *arg)
   error (_("dynamic_cast failed"));
 }
 
-/* Create a value of type TYPE that is zero, and return it.  */
-
-struct value *
-value_zero (struct type *type, enum lval_type lv)
-{
-  struct value *val = allocate_value (type);
-
-  VALUE_LVAL (val) = (lv == lval_computed ? not_lval : lv);
-  return val;
-}
-
 /* Create a not_lval value of numeric type TYPE that is one, and return it.  */
 
 struct value *
index 3aa5fac23069d45ae3b73e9847302c6ecc4bf4f9..19d81fd6e357ab669edb25226873bc42f4529a6c 100644 (file)
@@ -180,6 +180,7 @@ struct value
       lazy (1),
       initialized (1),
       stack (0),
+      is_zero (false),
       type (type_),
       enclosing_type (type_)
   {
@@ -230,6 +231,10 @@ struct value
      used instead of read_memory to enable extra caching.  */
   unsigned int stack : 1;
 
+  /* True if this is a zero value, created by 'value_zero'; false
+     otherwise.  */
+  bool is_zero : 1;
+
   /* Location of value (if lval).  */
   union
   {
@@ -1704,6 +1709,7 @@ value_copy (struct value *arg)
   val->pointed_to_offset = arg->pointed_to_offset;
   val->modifiable = arg->modifiable;
   val->stack = arg->stack;
+  val->is_zero = arg->is_zero;
   val->initialized = arg->initialized;
   if (!value_lazy (val))
     {
@@ -3507,6 +3513,18 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
 }
 
 
+/* Create a value of type TYPE that is zero, and return it.  */
+
+struct value *
+value_zero (struct type *type, enum lval_type lv)
+{
+  struct value *val = allocate_value_lazy (type);
+
+  VALUE_LVAL (val) = (lv == lval_computed ? not_lval : lv);
+  val->is_zero = true;
+  return val;
+}
+
 /* Convert C numbers into newly allocated values.  */
 
 struct value *
@@ -4026,7 +4044,11 @@ value_fetch_lazy (struct value *val)
      value.  */
   gdb_assert (val->optimized_out.empty ());
   gdb_assert (val->unavailable.empty ());
-  if (value_bitsize (val))
+  if (val->is_zero)
+    {
+      /* Nothing.  */
+    }
+  else if (value_bitsize (val))
     value_fetch_lazy_bitfield (val);
   else if (VALUE_LVAL (val) == lval_memory)
     value_fetch_lazy_memory (val);