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 .
+
+# 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 .
+
+with Interfaces;
+
+procedure Main is
+ X : Interfaces.Unsigned_64 := Interfaces.Unsigned_64'Last;
+begin
+ null; -- START
+end Main;