diff options
author | Tom Tromey <tromey@adacore.com> | 2021-09-24 14:06:52 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2021-10-19 13:03:58 -0600 |
commit | 05fb05a94729473cb04b1299fe5c36e06525c78f (patch) | |
tree | aedea01744e7289d9faef886a9ab2a2931edbdca | |
parent | d7c68312bdeca52e242326e5cf155e0aa63268bb (diff) | |
download | binutils-05fb05a94729473cb04b1299fe5c36e06525c78f.zip binutils-05fb05a94729473cb04b1299fe5c36e06525c78f.tar.gz binutils-05fb05a94729473cb04b1299fe5c36e06525c78f.tar.bz2 |
Fix bug in dynamic type resolution
A customer-reported problem led us to a bug in dynamic type
resolution. resolve_dynamic_struct will recursively call
resolve_dynamic_type_internal, passing it the sub-object for the
particular field being resolved. While it offsets the address here,
it does not also offset the "valaddr" -- the array of bytes describing
the memory.
This patch fixes the bug, by offsetting both. A test case is included
that can be used to reproduce the bug.
-rw-r--r-- | gdb/gdbtypes.c | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/array_of_variant.exp | 11 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/array_of_variant/p.adb | 20 |
3 files changed, 35 insertions, 3 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index de73a2b..3110395 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2615,10 +2615,11 @@ resolve_dynamic_struct (struct type *type, " (invalid location kind)")); pinfo.type = check_typedef (resolved_type->field (i).type ()); + size_t offset = TYPE_FIELD_BITPOS (resolved_type, i) / TARGET_CHAR_BIT; pinfo.valaddr = addr_stack->valaddr; - pinfo.addr - = (addr_stack->addr - + (TYPE_FIELD_BITPOS (resolved_type, i) / TARGET_CHAR_BIT)); + if (!pinfo.valaddr.empty ()) + pinfo.valaddr = pinfo.valaddr.slice (offset); + pinfo.addr = addr_stack->addr + offset; pinfo.next = addr_stack; resolved_type->field (i).set_type diff --git a/gdb/testsuite/gdb.ada/array_of_variant.exp b/gdb/testsuite/gdb.ada/array_of_variant.exp index 6372e2c..f8f4d9c 100644 --- a/gdb/testsuite/gdb.ada/array_of_variant.exp +++ b/gdb/testsuite/gdb.ada/array_of_variant.exp @@ -97,4 +97,15 @@ foreach_with_prefix scenario {all minimal} { [string_to_regexp "$v2"] \ "python print second array element" } + + set av1 "(initial => 0, rest => (tag => unused, cval => 88 'X'))" + set av2 "(initial => 0, rest => (tag => object, ival => 88))" + set full "($av1, $av2)" + + gdb_test "print another_array(1)" " = [string_to_regexp $av1]" \ + "print first element of another_array" + gdb_test "print another_array(2)" " = [string_to_regexp $av2]" \ + "print second element of another_array" + gdb_test "print another_array" " = [string_to_regexp $full]" \ + "print another_array" } diff --git a/gdb/testsuite/gdb.ada/array_of_variant/p.adb b/gdb/testsuite/gdb.ada/array_of_variant/p.adb index c475eb4..bf087af 100644 --- a/gdb/testsuite/gdb.ada/array_of_variant/p.adb +++ b/gdb/testsuite/gdb.ada/array_of_variant/p.adb @@ -33,7 +33,27 @@ procedure P is Objects : array (1 .. 2) of Payload_T; + type Another_Type (Tag : Tag_T := Unused) is + record + case Tag is + when Unused => + CVal : Character; + when Object => + IVal : Integer; + end case; + end record; + + type Enclosing is record + Initial : Integer; + Rest : Another_Type; + end record; + + Another_Array : array (1 .. 2) of Enclosing + := ((Initial => 0, Rest => (Tag => Unused, CVal => 'X')), + (Initial => 0, Rest => (Tag => Object, IVal => 88))); + begin Objects (1) := (Tag => Object, Values => (others => 2)); Do_Nothing (Objects'Address); -- START + Do_Nothing (Another_Array'Address); end P; |