More robust fix for 32bit issues. (#7735)
authorGereon Kremer <gkremer@stanford.edu>
Sat, 4 Dec 2021 01:40:40 +0000 (17:40 -0800)
committerGitHub <noreply@github.com>
Sat, 4 Dec 2021 01:40:40 +0000 (01:40 +0000)
This PR implements a more robust fix for the 32bit issues with GMP. Relying on mpz_sizeinbase proves to be very tricky for the corner cases. This PR instead does a simple comparison against the min and max values of the respective types.

src/util/integer_gmp_imp.cpp

index f1d927d090e47b6811c7b91b82c95fc1afab178e..8d9f7d0501d2a8fbf39d428524e20f8b78c36a0b 100644 (file)
@@ -460,13 +460,17 @@ int64_t Integer::getSigned64() const
     {
       return getLong();
     }
-    // ensure there is no overflow.
-    // mpz_sizeinbase ignores the sign bit, thus at most 63 bits.
-    CheckArgument(mpz_sizeinbase(d_value.get_mpz_t(), 2) < 64,
-                  this,
-                  "Overflow detected in Integer::getSigned64().");
-    return std::stoll(toString());
+    try
+    {
+      return std::stoll(toString());
+    }
+    catch (const std::exception& e)
+    {
+      CheckArgument(
+          false, this, "Overflow detected in Integer::getSigned64().");
+    }
   }
+  return 0;
 }
 uint64_t Integer::getUnsigned64() const
 {
@@ -480,12 +484,19 @@ uint64_t Integer::getUnsigned64() const
     {
       return getUnsignedLong();
     }
-    // ensure there isn't overflow
-    CheckArgument(mpz_sizeinbase(d_value.get_mpz_t(), 2) <= 64,
-                  this,
-                  "Overflow detected in Integer::getUnsigned64().");
-    return std::stoull(toString());
+    try
+    {
+      CheckArgument(
+          sgn() >= 0, this, "Overflow detected in Integer::getUnsigned64().");
+      return std::stoull(toString());
+    }
+    catch (const std::exception& e)
+    {
+      CheckArgument(
+          false, this, "Overflow detected in Integer::getUnsigned64().");
+    }
   }
+  return 0;
 }
 
 size_t Integer::hash() const { return gmpz_hash(d_value.get_mpz_t()); }