aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2019-06-04 08:13:20 -0700
committerPaul Eggert2019-06-04 08:34:15 -0700
commit7f4558e3d9edbdee6901e5fbcd4a4072f49ec5b9 (patch)
treea709f4f82777f6a5e2c16e7d417ba59b74e7b430
parentdd7bc5de3f59237f21e1c4b70f0ba97549ea1fb4 (diff)
downloademacs-7f4558e3d9edbdee6901e5fbcd4a4072f49ec5b9.tar.gz
emacs-7f4558e3d9edbdee6901e5fbcd4a4072f49ec5b9.zip
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.
-rw-r--r--doc/lispref/numbers.texi14
-rw-r--r--src/alloc.c6
-rw-r--r--src/bignum.c7
3 files changed, 15 insertions, 12 deletions
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index fbdd83fa86e..cae8babcb40 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -191,19 +191,19 @@ on 64-bit platforms.
191@cindex integer range 191@cindex integer range
192@cindex number of bignum bits, limit on 192@cindex number of bignum bits, limit on
193@defvar integer-width 193@defvar integer-width
194The value of this variable is a nonnegative integer that is an upper 194The value of this variable is a nonnegative integer that controls
195bound on the number of bits in a bignum. Integers outside the fixnum 195whether Emacs signals a range error when a large integer would be
196range are limited to absolute values less than 196calculated. Integers with absolute values less than
197@ifnottex 197@ifnottex
1982**@var{n}, 1982**@var{n},
199@end ifnottex 199@end ifnottex
200@tex 200@tex
201@math{2^{n}}, 201@math{2^{n}},
202@end tex 202@end tex
203where @var{n} is this variable's value. Attempts to create bignums outside 203where @var{n} is this variable's value, do not signal a range error.
204this range signal a range error. Setting this variable 204Attempts to create larger integers typically signal a range error,
205to zero disables creation of bignums; setting it to a large number can 205although there might be no signal if a larger integer can be created cheaply.
206cause Emacs to consume large quantities of memory if a computation 206Setting this variable to a large number can be costly if a computation
207creates huge integers. 207creates huge integers.
208@end defvar 208@end defvar
209 209
diff --git a/src/alloc.c b/src/alloc.c
index 5c5b56d02e9..64aaa8acdfa 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -7369,9 +7369,9 @@ The time is in seconds as a floating point value. */);
7369 doc: /* Accumulated number of garbage collections done. */); 7369 doc: /* Accumulated number of garbage collections done. */);
7370 7370
7371 DEFVAR_INT ("integer-width", integer_width, 7371 DEFVAR_INT ("integer-width", integer_width,
7372 doc: /* Maximum number of bits in bignums. 7372 doc: /* Maximum number N of bits in safely-calculated integers.
7373Integers outside the fixnum range are limited to absolute values less 7373Integers with absolute values less than 2**N do not signal a range error.
7374than 2**N, where N is this variable's value. N should be nonnegative. */); 7374N should be nonnegative. */);
7375 7375
7376 defsubr (&Scons); 7376 defsubr (&Scons);
7377 defsubr (&Slist); 7377 defsubr (&Slist);
diff --git a/src/bignum.c b/src/bignum.c
index 009d73118c2..3883d3a3944 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -82,8 +82,11 @@ static Lisp_Object
82make_bignum_bits (size_t bits) 82make_bignum_bits (size_t bits)
83{ 83{
84 /* The documentation says integer-width should be nonnegative, so 84 /* The documentation says integer-width should be nonnegative, so
85 a single comparison suffices even though 'bits' is unsigned. */ 85 comparing it to BITS works even though BITS is unsigned. Treat
86 if (integer_width < bits) 86 integer-width as if it were at least twice the machine integer width,
87 so that timefns.c can safely use bignums for double-precision
88 timestamps. */
89 if (integer_width < bits && 2 * max (INTMAX_WIDTH, UINTMAX_WIDTH) < bits)
87 overflow_error (); 90 overflow_error ();
88 91
89 struct Lisp_Bignum *b = ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Bignum, 92 struct Lisp_Bignum *b = ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Bignum,