aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.ada
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2025-04-15 09:08:52 -0600
committerTom Tromey <tromey@adacore.com>2025-05-06 09:01:54 -0600
commitba005d32b0f3d6a8f7a35b649ffe46304bd7d6fb (patch)
tree3a956750c89dcf43a6df7b02431ec5869a1ee7dc /gdb/testsuite/gdb.ada
parent0dac4dded2b023080236474d4aea442d764a5049 (diff)
downloadbinutils-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/gdb.ada')
-rw-r--r--gdb/testsuite/gdb.ada/packed_record_2.exp61
-rw-r--r--gdb/testsuite/gdb.ada/packed_record_2/exam.adb51
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;