1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-02-02 20:16:25 +00:00

Always allow at least double-precision bignums

Without this fix, Emacs can get into a tight loop reporting
a range error when calculating timestamps.
* doc/lispref/numbers.texi (Integer Basics):
* src/alloc.c (syms_of_alloc): Document this.
* src/bignum.c (make_bignum_bits): Always allow bignums
of at least twice the width of (u)intmax_t.
This commit is contained in:
Paul Eggert 2019-06-04 08:13:20 -07:00
parent dd7bc5de3f
commit 7f4558e3d9
3 changed files with 15 additions and 12 deletions

View File

@ -191,19 +191,19 @@ on 64-bit platforms.
@cindex integer range
@cindex number of bignum bits, limit on
@defvar integer-width
The value of this variable is a nonnegative integer that is an upper
bound on the number of bits in a bignum. Integers outside the fixnum
range are limited to absolute values less than
The value of this variable is a nonnegative integer that controls
whether Emacs signals a range error when a large integer would be
calculated. Integers with absolute values less than
@ifnottex
2**@var{n},
@end ifnottex
@tex
@math{2^{n}},
@end tex
where @var{n} is this variable's value. Attempts to create bignums outside
this range signal a range error. Setting this variable
to zero disables creation of bignums; setting it to a large number can
cause Emacs to consume large quantities of memory if a computation
where @var{n} is this variable's value, do not signal a range error.
Attempts to create larger integers typically signal a range error,
although there might be no signal if a larger integer can be created cheaply.
Setting this variable to a large number can be costly if a computation
creates huge integers.
@end defvar

View File

@ -7369,9 +7369,9 @@ The time is in seconds as a floating point value. */);
doc: /* Accumulated number of garbage collections done. */);
DEFVAR_INT ("integer-width", integer_width,
doc: /* Maximum number of bits in bignums.
Integers outside the fixnum range are limited to absolute values less
than 2**N, where N is this variable's value. N should be nonnegative. */);
doc: /* Maximum number N of bits in safely-calculated integers.
Integers with absolute values less than 2**N do not signal a range error.
N should be nonnegative. */);
defsubr (&Scons);
defsubr (&Slist);

View File

@ -82,8 +82,11 @@ static Lisp_Object
make_bignum_bits (size_t bits)
{
/* The documentation says integer-width should be nonnegative, so
a single comparison suffices even though 'bits' is unsigned. */
if (integer_width < bits)
comparing it to BITS works even though BITS is unsigned. Treat
integer-width as if it were at least twice the machine integer width,
so that timefns.c can safely use bignums for double-precision
timestamps. */
if (integer_width < bits && 2 * max (INTMAX_WIDTH, UINTMAX_WIDTH) < bits)
overflow_error ();
struct Lisp_Bignum *b = ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Bignum,