diff options
author | Tom Tromey <tromey@adacore.com> | 2021-09-13 12:31:20 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2021-10-05 12:34:55 -0600 |
commit | 3e44c3049fc23f5ba894b346b7defdfba66b076e (patch) | |
tree | 5486581f3787291c83ff78c0506f63dce9711136 | |
parent | a519e8ffe2b0f008deaef1517562090d9eaadccc (diff) | |
download | gdb-3e44c3049fc23f5ba894b346b7defdfba66b076e.zip gdb-3e44c3049fc23f5ba894b346b7defdfba66b076e.tar.gz gdb-3e44c3049fc23f5ba894b346b7defdfba66b076e.tar.bz2 |
Allow lazy 'zero' value
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.
-rw-r--r-- | gdb/valops.c | 11 | ||||
-rw-r--r-- | gdb/value.c | 24 |
2 files changed, 23 insertions, 12 deletions
diff --git a/gdb/valops.c b/gdb/valops.c index a6c3632..f65479b 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -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 * diff --git a/gdb/value.c b/gdb/value.c index 3aa5fac..19d81fd 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -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); |