aboutsummaryrefslogtreecommitdiff
path: root/gdb/value.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2020-07-09 16:26:23 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2020-07-25 01:30:20 +0100
commite79eb02f2f09baecffb144bac6804f975065466f (patch)
treee1a92e0b6eb55bb577cb18a2caafab54685ab8d8 /gdb/value.c
parent719251fee155d5d4ede91f555e8898460e6b1731 (diff)
downloadfsf-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.c23
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 *