public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Fix range type signed-ness heuristic
@ 2022-11-15 18:49 Tom Tromey
  2022-11-28 14:18 ` Tom Tromey
  0 siblings, 1 reply; 2+ messages in thread
From: Tom Tromey @ 2022-11-15 18:49 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

The code to create a range type has a heuristic to decide whether the
range is unsigned.  However, this heuristic can fail if the upper
bound of the range has its high bit set, because the test is done
using LONGEST.

With this patch, if the underlying type of a range is unsigned, then
the range will always be unsigned.  A new test is included.

Regression tested on x86-64 Fedora 34.  We've also been using this
internally at AdaCore for a while.
---
 gdb/gdbtypes.c                               | 24 ++++++++-----
 gdb/testsuite/gdb.ada/unsigned_last.exp      | 38 ++++++++++++++++++++
 gdb/testsuite/gdb.ada/unsigned_last/main.adb | 22 ++++++++++++
 3 files changed, 76 insertions(+), 8 deletions(-)
 create mode 100644 gdb/testsuite/gdb.ada/unsigned_last.exp
 create mode 100644 gdb/testsuite/gdb.ada/unsigned_last/main.adb

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index a43d9265ad2..5e8a486d28f 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -958,7 +958,13 @@ create_range_type (struct type *result_type, struct type *index_type,
 
   if (index_type->code () == TYPE_CODE_FIXED_POINT)
     result_type->set_is_unsigned (index_type->is_unsigned ());
-  /* Note that the signed-ness of a range type can't simply be copied
+  else if (index_type->is_unsigned ())
+    {
+      /* If the underlying type is unsigned, then the range
+	 necessarily is.  */
+      result_type->set_is_unsigned (true);
+    }
+  /* Otherwise, the signed-ness of a range type can't simply be copied
      from the underlying type.  Consider a case where the underlying
      type is 'int', but the range type can hold 0..65535, and where
      the range is further specified to fit into 16 bits.  In this
@@ -966,13 +972,15 @@ create_range_type (struct type *result_type, struct type *index_type,
      range values will cause an unwanted sign extension.  So, we have
      some heuristics here instead.  */
   else if (low_bound->kind () == PROP_CONST && low_bound->const_val () >= 0)
-    result_type->set_is_unsigned (true);
-  /* Ada allows the declaration of range types whose upper bound is
-     less than the lower bound, so checking the lower bound is not
-     enough.  Make sure we do not mark a range type whose upper bound
-     is negative as unsigned.  */
-  if (high_bound->kind () == PROP_CONST && high_bound->const_val () < 0)
-    result_type->set_is_unsigned (false);
+    {
+      result_type->set_is_unsigned (true);
+      /* Ada allows the declaration of range types whose upper bound is
+	 less than the lower bound, so checking the lower bound is not
+	 enough.  Make sure we do not mark a range type whose upper bound
+	 is negative as unsigned.  */
+      if (high_bound->kind () == PROP_CONST && high_bound->const_val () < 0)
+	result_type->set_is_unsigned (false);
+    }
 
   result_type->set_endianity_is_not_default
     (index_type->endianity_is_not_default ());
diff --git a/gdb/testsuite/gdb.ada/unsigned_last.exp b/gdb/testsuite/gdb.ada/unsigned_last.exp
new file mode 100644
index 00000000000..f07d9483bbd
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/unsigned_last.exp
@@ -0,0 +1,38 @@
+# Copyright 2022 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/>.
+
+# Check that 'Last correctly results in an unsigned integer in when
+# the underlying type is unsigned.
+
+load_lib "ada.exp"
+
+if { [skip_ada_tests] } { return -1 }
+
+standard_ada_testfile main
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+  return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "START" ${testdir}/main.adb]
+runto "main.adb:$bp_location"
+
+# Check that both X and Unsigned_64'Last are printed as unsigned
+# values.  Previously the heuristic used when determining if a range
+# type was unsigned did not catch the latter case.
+gdb_test "print x" "= 18446744073709551615"
+gdb_test "print Unsigned_64'Last" "= 18446744073709551615"
diff --git a/gdb/testsuite/gdb.ada/unsigned_last/main.adb b/gdb/testsuite/gdb.ada/unsigned_last/main.adb
new file mode 100644
index 00000000000..f01e27e8ccc
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/unsigned_last/main.adb
@@ -0,0 +1,22 @@
+--  Copyright 2022 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/>.
+
+with Interfaces;
+
+procedure Main is
+   X : Interfaces.Unsigned_64 := Interfaces.Unsigned_64'Last;
+begin
+   null; -- START
+end Main;
-- 
2.34.3


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix range type signed-ness heuristic
  2022-11-15 18:49 [PATCH] Fix range type signed-ness heuristic Tom Tromey
@ 2022-11-28 14:18 ` Tom Tromey
  0 siblings, 0 replies; 2+ messages in thread
From: Tom Tromey @ 2022-11-28 14:18 UTC (permalink / raw)
  To: Tom Tromey via Gdb-patches; +Cc: Tom Tromey

>>>>> "Tom" == Tom Tromey via Gdb-patches <gdb-patches@sourceware.org> writes:

Tom> The code to create a range type has a heuristic to decide whether the
Tom> range is unsigned.  However, this heuristic can fail if the upper
Tom> bound of the range has its high bit set, because the test is done
Tom> using LONGEST.

Tom> With this patch, if the underlying type of a range is unsigned, then
Tom> the range will always be unsigned.  A new test is included.

Tom> Regression tested on x86-64 Fedora 34.  We've also been using this
Tom> internally at AdaCore for a while.

I'm checking this in now.

Tom

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-11-28 14:18 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-15 18:49 [PATCH] Fix range type signed-ness heuristic Tom Tromey
2022-11-28 14:18 ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).