diff --git a/py/parsenum.c b/py/parsenum.c index e18002306a25..4239f2dcd4d0 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -64,7 +64,7 @@ typedef mp_int_t parsed_int_t; typedef unsigned long long parsed_int_t; #define PARSED_INT_MUL_OVERFLOW mp_mul_ull_overflow -#define PARSED_INT_FITS(I) ((I) <= (unsigned long long)LLONG_MAX) +#define PARSED_INT_FITS(I) ((I) <= (unsigned long long)LLONG_MAX + 1) #endif mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, mp_lexer_t *lex) { @@ -135,8 +135,11 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m have_ret_val: #else // The PARSED_INT_FITS check above ensures parsed_val won't overflow signed long long - long long signed_val = parsed_val; - if (neg) { + long long signed_val = -parsed_val; + if (!neg) { + if (signed_val == LLONG_MIN) { + goto overflow; + } signed_val = -signed_val; } ret_val = mp_obj_new_int_from_ll(signed_val); // Could be large or small int diff --git a/tests/basics/int_64_basics.py b/tests/basics/int_64_basics.py index 2a161dac0ba1..ef76793317ec 100644 --- a/tests/basics/int_64_basics.py +++ b/tests/basics/int_64_basics.py @@ -151,3 +151,11 @@ print((1 << 48) << -6) except ValueError as e: print(e) + +# Test that the most extreme 64 bit integer values all parse with int() +print(int("-9223372036854775807")) +print(int("-9223372036854775808")) +print(int("9223372036854775807")) + +# Test that the most negative 64 bit integer can be formed via arithmetic +print(-9223372036854775807-1)