From: Tom Tromey Date: Thu, 11 Dec 2025 19:31:40 +0000 (-0700) Subject: Fix Ada 'Modulus attribute X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6193dd2f7cc21d39dce5076acbbb4b0869e70fcd;p=thirdparty%2Fbinutils-gdb.git Fix Ada 'Modulus attribute The internal AdaCore test suite pointed out that my earlier patch to displaying modular types broke the 'Modulus attribute -- it was off-by-one. While fixing this, though, I realized that the earlier 'ptype' problem also affected this attribute. So, this patch implements a similar fix in the parser. This adds some operator+ overloads to gdb_mpz for convenience. That class still doesn't have the full complement of operators -- they are added as needed. --- diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y index 09074e6d927..a714a7b907c 100644 --- a/gdb/ada-exp.y +++ b/gdb/ada-exp.y @@ -951,7 +951,16 @@ primary : primary TICK_ACCESS = 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 ()); + gdb_mpz modulus = gdb_mpz (*bound) + 1; + /* Pick something that's almost certainly + large enough. */ + struct type *r_type + = language_lookup_primitive_type (pstate->language (), + pstate->gdbarch (), + "unsigned_long_long_long_integer"); + pstate->push_new (r_type, + modulus); + ada_wrap (); } ; diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h index c2c90ad1189..a270c2b3570 100644 --- a/gdb/gmp-utils.h +++ b/gdb/gmp-utils.h @@ -225,13 +225,32 @@ struct gdb_mpz return *this; } - gdb_mpz operator+ (const gdb_mpz &other) const + gdb_mpz operator+ (const gdb_mpz &other) const & { gdb_mpz result; mpz_add (result.m_val, m_val, other.m_val); return result; } + gdb_mpz operator+ (const gdb_mpz &other) && + { + mpz_add (m_val, m_val, other.m_val); + return *this; + } + + gdb_mpz operator+ (unsigned long val) const & + { + gdb_mpz result; + mpz_add_ui (result.m_val, m_val, val); + return result; + } + + gdb_mpz operator+ (unsigned long val) && + { + mpz_add_ui (m_val, m_val, val); + return *this; + } + gdb_mpz &operator-= (unsigned long other) { mpz_sub_ui (m_val, m_val, other); diff --git a/gdb/testsuite/gdb.ada/modular.exp b/gdb/testsuite/gdb.ada/modular.exp index 9d2a000de81..7b79e7322fb 100644 --- a/gdb/testsuite/gdb.ada/modular.exp +++ b/gdb/testsuite/gdb.ada/modular.exp @@ -34,3 +34,7 @@ runto "prog.adb:$bp_location" # was displayed, gdb would say "mod 0". gdb_test "ptype mod1_type" "type = mod 4294967296" gdb_test "ptype mod2_type" "type = mod 18446744073709551616" + +gdb_test "print mod1_type'Modulus" " = 4294967296" +gdb_test "print mod2_type'Modulus" " = 18446744073709551616" +gdb_test "print mod3_type'Modulus" " = 4" diff --git a/gdb/testsuite/gdb.ada/modular/prog.adb b/gdb/testsuite/gdb.ada/modular/prog.adb index aa91148aab4..a5197bdc8e7 100644 --- a/gdb/testsuite/gdb.ada/modular/prog.adb +++ b/gdb/testsuite/gdb.ada/modular/prog.adb @@ -16,6 +16,7 @@ procedure Prog is type Mod1_Type_Base is mod 2 ** 32; type Mod2_Type_Base is mod 2 ** 64; + type Mod3_Type is mod 4; -- We use subtypes here because GCC emits the above modular types -- as base types with the expected size, which gdb then displays @@ -26,6 +27,7 @@ procedure Prog is X : Mod1_Type := 23; Y : Mod2_Type := 91; + Z : Mod3_Type := 2; begin null; -- STOP