]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Fix Ada 'Modulus attribute
authorTom Tromey <tromey@adacore.com>
Thu, 11 Dec 2025 19:31:40 +0000 (12:31 -0700)
committerTom Tromey <tromey@adacore.com>
Mon, 5 Jan 2026 19:12:58 +0000 (12:12 -0700)
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.

gdb/ada-exp.y
gdb/gmp-utils.h
gdb/testsuite/gdb.ada/modular.exp
gdb/testsuite/gdb.ada/modular/prog.adb

index 09074e6d927f78931cbd72f638a53ee5cceca2ff..a714a7b907c4318cef85f08f7f770de9c3676f1f 100644 (file)
@@ -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<long_const_operation> (r_type,
+                                                                 modulus);
+                         ada_wrap<ada_wrapped_operation> ();
                        }
        ;
 
index c2c90ad1189385521285369ee6b0a735a6e26664..a270c2b3570ca391b94783292c4c18c4932b57dc 100644 (file)
@@ -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);
index 9d2a000de813d4285d3a00f7b92bdac8c2c219b1..7b79e7322fb5c0440954e97a8dda7f8c8ab3a8a2 100644 (file)
@@ -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"
index aa91148aab484b5bf6fe8f92f52afeda5438f640..a5197bdc8e787a85e0ecd6fc58cc61f7afd7e3c0 100644 (file)
@@ -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