struct type *type_arg = check_typedef ($1);
if (!ada_is_modular_type (type_arg))
error (_("'modulus must be applied to modular type"));
- write_int (pstate, ada_modulus (type_arg),
- type_arg->target_type ());
+ std::optional<ULONGEST> bound
+ = ada_modular_bound (type_arg);
+ if (!bound.has_value ())
+ error (_("'modulus applied to type with non-constant bound"));
+ write_int (pstate, *bound, type_arg->target_type ());
}
;
int bit_size, bit_pos;
ULONGEST mod;
- mod = ada_modulus (arr->type ()) - 1;
+ mod = ada_modular_bound (arr->type ()).value_or (0);
bit_size = 0;
while (mod > 0)
{
&& subranged_type->is_unsigned ());
}
-/* Assuming ada_is_modular_type (TYPE), the modulus of TYPE. */
+/* See ada-lang.h. */
-ULONGEST
-ada_modulus (struct type *type)
+std::optional<ULONGEST>
+ada_modular_bound (struct type *type)
{
const dynamic_prop &high = type->bounds ()->high;
if (high.is_constant ())
- return (ULONGEST) high.const_val () + 1;
+ return (ULONGEST) high.const_val ();
- /* If TYPE is unresolved, the high bound might be a location list. Return
- 0, for lack of a better value to return. */
- return 0;
+ /* If TYPE is unresolved, the high bound might be a location
+ list. */
+ return {};
}
\f
extern bool ada_is_modular_type (struct type *);
-extern ULONGEST ada_modulus (struct type *);
+/* Return the upper bound of a modular type. If the upper bound is
+ non-constant, returns an empty optional. */
+
+extern std::optional<ULONGEST> ada_modular_bound (struct type *);
extern struct value *ada_value_ind (struct value *);
gdb_printf (stream, ">");
}
else if (ada_is_modular_type (type))
- gdb_printf (stream, "mod %s",
- int_string (ada_modulus (type), 10, 0, 0, 1));
+ {
+ std::optional<ULONGEST> bound = ada_modular_bound (type);
+ gdb_mpz modulus;
+ if (bound.has_value ())
+ {
+ modulus = *bound;
+ modulus += 1;
+ }
+ else
+ modulus = 0;
+ gdb_printf (stream, "mod %s", modulus.str ().c_str ());
+ }
else
{
gdb_printf (stream, "range ");
--- /dev/null
+# 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/>.
+
+# Test for a bug when printing a large modular type.
+
+load_lib "ada.exp"
+
+require allow_ada_tests
+
+standard_ada_testfile prog
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+ return
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/prog.adb]
+runto "prog.adb:$bp_location"
+
+# The bug was that a modular type with a size equal to gdb's ULONGEST
+# was displayed, gdb would say "mod 0".
+gdb_test "ptype mod1_type" "type = mod 4294967296"
+gdb_test "ptype mod2_type" "type = mod 18446744073709551616"
--- /dev/null
+-- 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 Prog is
+ type Mod1_Type_Base is mod 2 ** 32;
+ type Mod2_Type_Base is mod 2 ** 64;
+
+ -- We use subtypes here because GCC emits the above modular types
+ -- as base types with the expected size, which gdb then displays
+ -- as <4-byte integer> (e.g.). However we want to see the real
+ -- modular type display.
+ subtype Mod1_Type is Mod1_Type_Base;
+ subtype Mod2_Type is Mod2_Type_Base;
+
+ X : Mod1_Type := 23;
+ Y : Mod2_Type := 91;
+
+begin
+ null; -- STOP
+end Prog;