diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-07-09 16:26:23 +0100 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-07-25 01:30:20 +0100 |
commit | e79eb02f2f09baecffb144bac6804f975065466f (patch) | |
tree | e1a92e0b6eb55bb577cb18a2caafab54685ab8d8 /gdb/value.c | |
parent | 719251fee155d5d4ede91f555e8898460e6b1731 (diff) | |
download | fsf-binutils-gdb-e79eb02f2f09baecffb144bac6804f975065466f.zip fsf-binutils-gdb-e79eb02f2f09baecffb144bac6804f975065466f.tar.gz fsf-binutils-gdb-e79eb02f2f09baecffb144bac6804f975065466f.tar.bz2 |
gdb/fortran: resolve dynamic types when readjusting after an indirection
After dereferencing a pointer (in value_ind) or following a
reference (in coerce_ref) we call readjust_indirect_value_type to
"fixup" the type of the resulting value object.
This fixup handles cases relating to the type of the resulting object
being different (a sub-class) of the original pointers target type.
If we encounter a pointer to a dynamic type then after dereferencing a
pointer (in value_ind) the type of the object created will have had
its dynamic type resolved. However, in readjust_indirect_value_type,
we use the target type of the original pointer to "fixup" the type of
the resulting value. In this case, the target type will be a dynamic
type, so the resulting value object, once again has a dynamic type.
This then triggers an assertion later within GDB.
The solution I propose here is that we call resolve_dynamic_type on
the pointer's target type (within readjust_indirect_value_type) so
that the resulting value is not converted back to a dynamic type.
The test case is based on the original test in the bug report.
gdb/ChangeLog:
PR fortran/23051
PR fortran/26139
* valops.c (value_ind): Pass address to
readjust_indirect_value_type.
* value.c (readjust_indirect_value_type): Make parameter
non-const, and add extra address parameter. Resolve original type
before using it.
* value.h (readjust_indirect_value_type): Update function
signature and comment.
gdb/testsuite/ChangeLog:
PR fortran/23051
PR fortran/26139
* gdb.fortran/class-allocatable-array.exp: New file.
* gdb.fortran/class-allocatable-array.f90: New file.
* gdb.fortran/pointer-to-pointer.exp: New file.
* gdb.fortran/pointer-to-pointer.f90: New file.
Diffstat (limited to 'gdb/value.c')
-rw-r--r-- | gdb/value.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/gdb/value.c b/gdb/value.c index 3a5b02b..aac9baaa 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -3629,10 +3629,20 @@ coerce_ref_if_computed (const struct value *arg) struct value * readjust_indirect_value_type (struct value *value, struct type *enc_type, const struct type *original_type, - const struct value *original_value) + struct value *original_value, + CORE_ADDR original_value_address) { + gdb_assert (original_type->code () == TYPE_CODE_PTR + || TYPE_IS_REFERENCE (original_type)); + + struct type *original_target_type = TYPE_TARGET_TYPE (original_type); + gdb::array_view<const gdb_byte> view; + struct type *resolved_original_target_type + = resolve_dynamic_type (original_target_type, view, + original_value_address); + /* Re-adjust type. */ - deprecated_set_value_type (value, TYPE_TARGET_TYPE (original_type)); + deprecated_set_value_type (value, resolved_original_target_type); /* Add embedding info. */ set_value_enclosing_type (value, enc_type); @@ -3659,12 +3669,11 @@ coerce_ref (struct value *arg) enc_type = check_typedef (value_enclosing_type (arg)); enc_type = TYPE_TARGET_TYPE (enc_type); - retval = value_at_lazy (enc_type, - unpack_pointer (value_type (arg), - value_contents (arg))); + CORE_ADDR addr = unpack_pointer (value_type (arg), value_contents (arg)); + retval = value_at_lazy (enc_type, addr); enc_type = value_type (retval); - return readjust_indirect_value_type (retval, enc_type, - value_type_arg_tmp, arg); + return readjust_indirect_value_type (retval, enc_type, value_type_arg_tmp, + arg, addr); } struct value * |