aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/gmp-utils.c10
-rw-r--r--gdb/gmp-utils.h48
2 files changed, 52 insertions, 6 deletions
diff --git a/gdb/gmp-utils.c b/gdb/gmp-utils.c
index 0afa344..13fa61d 100644
--- a/gdb/gmp-utils.c
+++ b/gdb/gmp-utils.c
@@ -69,19 +69,21 @@ void
gdb_mpz::export_bits (gdb::array_view<gdb_byte> buf, int endian, bool unsigned_p,
bool safe) const
{
- gdb_assert (buf.size () > 0);
-
int sign = mpz_sgn (m_val);
if (sign == 0)
{
/* Our value is zero, so no need to call mpz_export to do the work,
especially since mpz_export's documentation explicitly says
that the function is a noop in this case. Just write zero to
- BUF ourselves. */
- memset (buf.data (), 0, buf.size ());
+ BUF ourselves, if it is non-empty. In some languages, a
+ zero-bit type can exist and this is also fine. */
+ if (buf.size () > 0)
+ memset (buf.data (), 0, buf.size ());
return;
}
+ gdb_assert (buf.size () > 0);
+
if (safe)
{
/* Determine the maximum range of values that our buffer can
diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h
index f294ab6..d05c11e 100644
--- a/gdb/gmp-utils.h
+++ b/gdb/gmp-utils.h
@@ -119,11 +119,17 @@ struct gdb_mpz
return result;
}
- /* Convert VAL to an integer of the given type.
+ /* Convert this value to an integer of the given type.
The return type can signed or unsigned, with no size restriction. */
template<typename T> T as_integer () const;
+ /* Convert this value to an integer of the given type. If this
+ value is too large, it is truncated.
+
+ The return type can signed or unsigned, with no size restriction. */
+ template<typename T> T as_integer_truncate () const;
+
/* Set VAL by importing the number stored in the byte array (BUF),
using the given BYTE_ORDER. The size of the data to read is
the byte array's size.
@@ -312,7 +318,7 @@ struct gdb_mpz
return mpz_cmp (m_val, other.m_val) <= 0;
}
- bool operator< (int other) const
+ bool operator< (long other) const
{
return mpz_cmp_si (m_val, other) < 0;
}
@@ -322,6 +328,28 @@ struct gdb_mpz
return mpz_cmp_si (m_val, other) == 0;
}
+ bool operator== (long other) const
+ {
+ return mpz_cmp_si (m_val, other) == 0;
+ }
+
+ bool operator== (unsigned long other) const
+ {
+ return mpz_cmp_ui (m_val, other) == 0;
+ }
+
+ template<typename T,
+ typename = gdb::Requires<
+ gdb::And<std::is_integral<T>,
+ std::integral_constant<bool,
+ (sizeof (T) > sizeof (long))>>
+ >
+ >
+ bool operator== (T src)
+ {
+ return *this == gdb_mpz (src);
+ }
+
bool operator== (const gdb_mpz &other) const
{
return mpz_cmp (m_val, other.m_val) == 0;
@@ -612,4 +640,20 @@ gdb_mpz::as_integer () const
return result;
}
+/* See declaration above. */
+
+template<typename T>
+T
+gdb_mpz::as_integer_truncate () const
+{
+ T result;
+
+ this->export_bits ({(gdb_byte *) &result, sizeof (result)},
+ 0 /* endian (0 = native) */,
+ !std::is_signed<T>::value /* unsigned_p */,
+ false /* safe */);
+
+ return result;
+}
+
#endif