Skip to content

Commit 9c74c05

Browse files
address min-int overflow reported in #2565
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent 77ef40a commit 9c74c05

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

src/test/mpz.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,19 @@ void tst_int_min_bug() {
293293
m.del(r);
294294
}
295295

296+
void tst_int64_min_bug() {
297+
synch_mpz_manager m;
298+
mpz intmin;
299+
mpz test;
300+
m.set(test, "-9223372036854775808");
301+
m.set(intmin, std::numeric_limits<int64_t>::min());
302+
std::cout << "minint: " << m.to_string(intmin) << "\n";
303+
ENSURE(m.eq(test, intmin));
304+
m.del(intmin);
305+
m.del(test);
306+
}
307+
308+
296309
void tst_scoped() {
297310
synch_mpz_manager m;
298311
scoped_synch_mpz a(m);
@@ -504,6 +517,7 @@ void tst_mpz() {
504517
// tst_gcd();
505518
tst_scoped();
506519
tst_int_min_bug();
520+
tst_int64_min_bug();
507521
bug4();
508522
bug3();
509523
bug1();

src/util/mpz.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,12 @@ void mpz_manager<SYNCH>::set_big_i64(mpz & c, int64_t v) {
272272
c.m_kind = mpz_large;
273273
SASSERT(capacity(c) >= m_init_cell_capacity);
274274
uint64_t _v;
275-
if (v < 0) {
275+
if (v == std::numeric_limits<int64_t>::min()) {
276+
// min-int is even
277+
_v = -(v/2);
278+
c.m_val = -1;
279+
}
280+
else if (v < 0) {
276281
_v = -v;
277282
c.m_val = -1;
278283
}
@@ -298,14 +303,15 @@ void mpz_manager<SYNCH>::set_big_i64(mpz & c, int64_t v) {
298303
}
299304
c.m_kind = mpz_large;
300305
uint64_t _v;
301-
bool sign;
302-
if (v < 0) {
306+
bool sign = v < 0;
307+
if (v == std::numeric_limits<int64_t>::min()) {
308+
_v = -(v/2);
309+
}
310+
else if (v < 0) {
303311
_v = -v;
304-
sign = true;
305312
}
306313
else {
307314
_v = v;
308-
sign = false;
309315
}
310316
mpz_set_ui(*c.m_ptr, static_cast<unsigned>(_v));
311317
MPZ_BEGIN_CRITICAL();
@@ -316,6 +322,9 @@ void mpz_manager<SYNCH>::set_big_i64(mpz & c, int64_t v) {
316322
if (sign)
317323
mpz_neg(*c.m_ptr, *c.m_ptr);
318324
#endif
325+
if (v == std::numeric_limits<int64_t>::min()) {
326+
big_add(c, c, c);
327+
}
319328
}
320329

321330
template<bool SYNCH>

0 commit comments

Comments
 (0)