From mercurial at gmplib.org Sun Nov 1 11:24:28 2026 From: mercurial at gmplib.org (mercurial at gmplib.org) Date: Sun, 01 Nov 2026 11:24:28 +0100 Subject: [Gmp-commit] /var/hg/gmp: Fix LONG_MIN / mpz_class(-1) Message-ID: details: /var/hg/gmp/rev/722f5c638d3a changeset: 18594:722f5c638d3a user: Marc Glisse date: Sun Nov 01 11:24:25 2026 +0100 description: Fix LONG_MIN / mpz_class(-1) diffstat: ChangeLog | 6 ++++++ gmpxx.h | 18 ++++++++++++++++-- tests/cxx/t-ops2z.cc | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diffs (60 lines): diff -r 19e57d407ade -r 722f5c638d3a ChangeLog --- a/ChangeLog Mon Oct 26 13:09:17 2026 +0100 +++ b/ChangeLog Sun Nov 01 11:24:25 2026 +0100 @@ -1,3 +1,9 @@ +2026-11-01 Marc Glisse + + * gmpxx.h (__gmp_binary_divides, __gmp_binary_modulus): Fix LONG_MIN / + mpz_class(-1). + * tests/cxx/t-ops2z.cc: Test it. + 2026-10-26 Jeff Bailey * gmp-h.in (_GMP_H_HAVE_FILE): Test also _LLVM_LIBC_STDIO_H (for diff -r 19e57d407ade -r 722f5c638d3a gmpxx.h --- a/gmpxx.h Mon Oct 26 13:09:17 2026 +0100 +++ b/gmpxx.h Sun Nov 01 11:24:25 2026 +0100 @@ -671,7 +671,17 @@ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) { if (mpz_fits_slong_p(w)) - mpz_set_si(z, l / mpz_get_si(w)); + { + signed long divisor = mpz_get_si(w); + // LONG_MIN / -1 is not representable as a signed long. + if (divisor == -1) + { + mpz_set_si(z, l); + mpz_neg(z, z); + } + else + mpz_set_si(z, l / divisor); + } else { /* if w is bigger than a long then the quotient must be zero, unless @@ -825,7 +835,11 @@ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) { if (mpz_fits_slong_p(w)) - mpz_set_si(z, l % mpz_get_si(w)); + { + signed long divisor = mpz_get_si(w); + // LONG_MIN % -1 is undefined in C++ even though the result is zero. + mpz_set_si(z, divisor == -1 ? 0 : l % divisor); + } else { /* if w is bigger than a long then the remainder is l unchanged, diff -r 19e57d407ade -r 722f5c638d3a tests/cxx/t-ops2z.cc --- a/tests/cxx/t-ops2z.cc Mon Oct 26 13:09:17 2026 +0100 +++ b/tests/cxx/t-ops2z.cc Sun Nov 01 11:24:25 2026 +0100 @@ -36,6 +36,8 @@ CHECK_ALL_SIGNS(mpz_class,17,2,%); CHECK(unsigned long,mpz_class,5,-2,/); CHECK(unsigned long,mpz_class,5,-2,%); + ASSERT_ALWAYS(LONG_MIN/mpz_class(-1)+LONG_MIN==0); + ASSERT_ALWAYS(LONG_MIN%mpz_class(-1)==0); ASSERT_ALWAYS(7ul/mpz_class(1e35)==0); ASSERT_ALWAYS(7ul%mpz_class(1e35)==7); ASSERT_ALWAYS(7ul/mpz_class(-1e35)==0);