From: Tom Tromey Date: Thu, 4 Dec 2025 14:36:59 +0000 (-0700) Subject: Fix 'ptype' of a certain Ada modular type X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e4861cb9ce250275d6be08e8a64d948a4f00008;p=thirdparty%2Fbinutils-gdb.git Fix 'ptype' of a certain Ada modular type If an Ada modular type is the same size as gdb's own ULONGEST, ptype will show "mod 0". This happens because ada_modulus does: return (ULONGEST) high.const_val () + 1; This patch cleans this up, replacing ada_modulus with a function to return the upper bound (if available), and then fixing the various callers. The type-printing caller still does the "+1", but now this is done with a gdb_mpz. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33690 Approved-By: Simon Marchi --- diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y index ed5694e2f1f..c87b91e92e0 100644 --- a/gdb/ada-exp.y +++ b/gdb/ada-exp.y @@ -947,8 +947,11 @@ primary : primary TICK_ACCESS 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 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 ()); } ; diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 21b081854a8..87ae5975788 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -2607,7 +2607,7 @@ decode_constrained_packed_array (struct value *arr) 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) { @@ -11638,19 +11638,19 @@ ada_is_modular_type (struct type *type) && 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 +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 {}; } diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h index c7430c713fd..6a5cc553275 100644 --- a/gdb/ada-lang.h +++ b/gdb/ada-lang.h @@ -326,7 +326,10 @@ extern const char *ada_enum_name (const char *); 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 ada_modular_bound (struct type *); extern struct value *ada_value_ind (struct value *); diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c index 2bafa5de68d..4a9152b3b7b 100644 --- a/gdb/ada-typeprint.c +++ b/gdb/ada-typeprint.c @@ -1040,8 +1040,18 @@ ada_print_type (struct type *type0, const char *varstring, 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 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 "); diff --git a/gdb/testsuite/gdb.ada/modular.exp b/gdb/testsuite/gdb.ada/modular.exp new file mode 100644 index 00000000000..9d2a000de81 --- /dev/null +++ b/gdb/testsuite/gdb.ada/modular.exp @@ -0,0 +1,36 @@ +# 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 . + +# 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" diff --git a/gdb/testsuite/gdb.ada/modular/prog.adb b/gdb/testsuite/gdb.ada/modular/prog.adb new file mode 100644 index 00000000000..aa91148aab4 --- /dev/null +++ b/gdb/testsuite/gdb.ada/modular/prog.adb @@ -0,0 +1,32 @@ +-- 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 . + +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;