diff options
author | Tom Tromey <tromey@adacore.com> | 2025-04-15 09:08:52 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2025-05-06 09:01:54 -0600 |
commit | ba005d32b0f3d6a8f7a35b649ffe46304bd7d6fb (patch) | |
tree | 3a956750c89dcf43a6df7b02431ec5869a1ee7dc /gdb/testsuite | |
parent | 0dac4dded2b023080236474d4aea442d764a5049 (diff) | |
download | binutils-ba005d32b0f3d6a8f7a35b649ffe46304bd7d6fb.zip binutils-ba005d32b0f3d6a8f7a35b649ffe46304bd7d6fb.tar.gz binutils-ba005d32b0f3d6a8f7a35b649ffe46304bd7d6fb.tar.bz2 |
Handle dynamic field properties
I found a situation where gdb could not properly decode an Ada type.
In this first scenario, the discriminant of a type is a bit-field.
PROP_ADDR_OFFSET does not handle this situation, because it only
allows an offset -- not a bit-size.
My original approach to this just added a bit size as well, but after
some discussion with Eric Botcazou, we found another failing case: a
tagged type can have a second discriminant that appears at a variable
offset.
So, this patch changes this code to accept a general 'struct field'
instead of trying to replicate the field-finding machinery by itself.
This is handled at property-evaluation time by simply using a 'field'
and resolving its dynamic properties. Then the usual field-extraction
function is called to get the value.
Because the baton now just holds a field, I renamed PROP_ADDR_OFFSET
to PROP_FIELD.
The DWARF reader now defers filling in the property baton until the
fields have been attached to the type.
Finally, I noticed that if the discriminant field has a biased
representation, then unpack_field_as_long would not handle this
either. This bug is also fixed here, and the test case checks this.
Regression tested on x86-64 Fedora 41.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/gdb.ada/packed_record_2.exp | 61 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/packed_record_2/exam.adb | 51 |
2 files changed, 112 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.ada/packed_record_2.exp b/gdb/testsuite/gdb.ada/packed_record_2.exp new file mode 100644 index 0000000..d0bcdbd --- /dev/null +++ b/gdb/testsuite/gdb.ada/packed_record_2.exp @@ -0,0 +1,61 @@ +# Copyright 2025 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile exam + +set flags {debug} +if {[ada_minimal_encodings]} { + lappend flags additional_flags=-fgnat-encodings=minimal +} + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/exam.adb] +runto "exam.adb:$bp_location" + +set spr_contents "discr => 3, field => -4, array_field => \\(-5, -6, -7\\)" + +gdb_test "print spr" " = \\($spr_contents\\)" + +gdb_test "print spr.discr" " = 3" + +# See PR ada/32880 -- gdb should probably print array (1 .. 3) here, +# but instead shows array (<>). However as this isn't totally +# relevant to this test, we just accept it. +gdb_test "ptype spr" \ + [multi_line \ + "type = tagged record" \ + " discr: range 1 .. 8;" \ + " field: range -7 .. -4;" \ + " array_field: array \\(<>\\) of exam.small <packed: 2-bit elements>;" \ + "end record"] + +gdb_test_multiple "print sc" "" { + -re " \\($spr_contents, outer => 2, another_array => \\(-7, -6\\)\\)" { + pass $gdb_test_name + } + -re " \\($spr_contents, outer => $decimal, another_array => \\(.*\\)\\)" { + # Other output is a known GCC bug. + xfail $gdb_test_name + } +} diff --git a/gdb/testsuite/gdb.ada/packed_record_2/exam.adb b/gdb/testsuite/gdb.ada/packed_record_2/exam.adb new file mode 100644 index 0000000..e528ecf --- /dev/null +++ b/gdb/testsuite/gdb.ada/packed_record_2/exam.adb @@ -0,0 +1,51 @@ +-- Copyright 2025 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. + +procedure Exam is + type Small is range -7 .. -4; + for Small'Size use 2; + + type Range_Int is range 1 .. 8; + for Range_Int'Size use 3; + + type Packed_Array is array (Range_Int range <>) of Small; + pragma pack (Packed_Array); + + type Some_Packed_Record (Discr : Range_Int) is tagged record + Field: Small; + Array_Field : Packed_Array (1 .. Discr); + end record; + pragma Pack (Some_Packed_Record); + + type Sub_Class (Inner, Outer : Range_Int) + is new Some_Packed_Record (Inner) with + record + Another_Array : Packed_Array (1 .. Outer); + end record; + pragma Pack (Sub_Class); + + SPR : Some_Packed_Record := (Discr => 3, + Field => -4, + Array_Field => (-5, -6, -7)); + + SC : Sub_Class := (Inner => 3, + Outer => 2, + Field => -4, + Array_Field => (-5, -6, -7), + Another_Array => (-7, -6)); + +begin + null; -- STOP +end Exam; |