aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ChangeLog8
-rw-r--r--src/bytecode.c6
-rw-r--r--src/data.c126
3 files changed, 91 insertions, 49 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index ccf1fea9514..435f90abad9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,13 @@
12011-05-03 Paul Eggert <eggert@cs.ucla.edu> 12011-05-03 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Arithmetic overflows now return float rather than wrapping around.
4 * data.c: Include <intprops.h>.
5 (arith_driver): Use floating point if the accumulator would otherwise
6 go out of EMACS_INT range.
7 (arith_driver, Fadd1, Fsub1): Use floating point if the result is
8 out of Emacs fixnum range.
9 * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate.
10
3 * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. 11 * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering.
4 12
5 * process.c (Fformat_network_address): Fix typo: args2 -> *args2. 13 * process.c (Fformat_network_address): Fix typo: args2 -> *args2.
diff --git a/src/bytecode.c b/src/bytecode.c
index c3cd3d43072..ce79b011bbb 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1186,7 +1186,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1186 { 1186 {
1187 Lisp_Object v1; 1187 Lisp_Object v1;
1188 v1 = TOP; 1188 v1 = TOP;
1189 if (INTEGERP (v1)) 1189 if (INTEGERP (v1) && MOST_NEGATIVE_FIXNUM < XINT (v1))
1190 { 1190 {
1191 XSETINT (v1, XINT (v1) - 1); 1191 XSETINT (v1, XINT (v1) - 1);
1192 TOP = v1; 1192 TOP = v1;
@@ -1204,7 +1204,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1204 { 1204 {
1205 Lisp_Object v1; 1205 Lisp_Object v1;
1206 v1 = TOP; 1206 v1 = TOP;
1207 if (INTEGERP (v1)) 1207 if (INTEGERP (v1) && XINT (v1) < MOST_POSITIVE_FIXNUM)
1208 { 1208 {
1209 XSETINT (v1, XINT (v1) + 1); 1209 XSETINT (v1, XINT (v1) + 1);
1210 TOP = v1; 1210 TOP = v1;
@@ -1290,7 +1290,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1290 { 1290 {
1291 Lisp_Object v1; 1291 Lisp_Object v1;
1292 v1 = TOP; 1292 v1 = TOP;
1293 if (INTEGERP (v1)) 1293 if (INTEGERP (v1) && - MOST_POSITIVE_FIXNUM <= XINT (v1))
1294 { 1294 {
1295 XSETINT (v1, - XINT (v1)); 1295 XSETINT (v1, - XINT (v1));
1296 TOP = v1; 1296 TOP = v1;
diff --git a/src/data.c b/src/data.c
index 577ae777d89..beff570d552 100644
--- a/src/data.c
+++ b/src/data.c
@@ -22,6 +22,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <signal.h> 22#include <signal.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <setjmp.h> 24#include <setjmp.h>
25
26#include <intprops.h>
27
25#include "lisp.h" 28#include "lisp.h"
26#include "puresize.h" 29#include "puresize.h"
27#include "character.h" 30#include "character.h"
@@ -2426,10 +2429,8 @@ static Lisp_Object float_arith_driver (double, size_t, enum arithop,
2426static Lisp_Object 2429static Lisp_Object
2427arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) 2430arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2428{ 2431{
2429 register Lisp_Object val;
2430 register size_t argnum; 2432 register size_t argnum;
2431 register EMACS_INT accum = 0; 2433 register EMACS_INT accum = 0;
2432 register EMACS_INT next;
2433 2434
2434 switch (SWITCH_ENUM_CAST (code)) 2435 switch (SWITCH_ENUM_CAST (code))
2435 { 2436 {
@@ -2451,58 +2452,89 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2451 2452
2452 for (argnum = 0; argnum < nargs; argnum++) 2453 for (argnum = 0; argnum < nargs; argnum++)
2453 { 2454 {
2455 EMACS_INT a = accum;
2456 int use_float = 0;
2457
2454 /* Using args[argnum] as argument to CHECK_NUMBER_... */ 2458 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2455 val = args[argnum]; 2459 Lisp_Object val = args[argnum];
2456 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 2460 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
2461 args[argnum] = val;
2457 2462
2458 if (FLOATP (val)) 2463 if (FLOATP (val))
2459 return float_arith_driver ((double) accum, argnum, code, 2464 use_float = 1;
2460 nargs, args); 2465 else
2461 args[argnum] = val;
2462 next = XINT (args[argnum]);
2463 switch (SWITCH_ENUM_CAST (code))
2464 { 2466 {
2465 case Aadd: 2467 EMACS_INT next = XINT (val);
2466 accum += next; 2468 switch (SWITCH_ENUM_CAST (code))
2467 break;
2468 case Asub:
2469 accum = argnum ? accum - next : nargs == 1 ? - next : next;
2470 break;
2471 case Amult:
2472 accum *= next;
2473 break;
2474 case Adiv:
2475 if (!argnum)
2476 accum = next;
2477 else
2478 { 2469 {
2479 if (next == 0) 2470 case Aadd:
2480 xsignal0 (Qarith_error); 2471 if (next < 0
2481 accum /= next; 2472 ? a < TYPE_MINIMUM (EMACS_INT) - next
2473 : TYPE_MAXIMUM (EMACS_INT) - next < a)
2474 use_float = 1;
2475 else
2476 a += next;
2477 break;
2478 case Asub:
2479 if (argnum == 0 && nargs != 1)
2480 a = next;
2481 else if (next < 0
2482 ? TYPE_MAXIMUM (EMACS_INT) + next < a
2483 : a < TYPE_MINIMUM (EMACS_INT) + next)
2484 use_float = 1;
2485 else
2486 a -= next;
2487 break;
2488 case Amult:
2489 if (next < 0
2490 ? (a < 0
2491 ? a < TYPE_MAXIMUM (EMACS_INT) / next
2492 : next != -1 && TYPE_MINIMUM (EMACS_INT) / next < a)
2493 : (next != 0
2494 && (a < 0
2495 ? a < TYPE_MINIMUM (EMACS_INT) / next
2496 : TYPE_MAXIMUM (EMACS_INT) / next < a)))
2497 use_float = 1;
2498 else
2499 a *= next;
2500 break;
2501 case Adiv:
2502 if (!argnum)
2503 a = next;
2504 else
2505 {
2506 if (next == 0)
2507 xsignal0 (Qarith_error);
2508 a /= next;
2509 }
2510 break;
2511 case Alogand:
2512 a &= next;
2513 break;
2514 case Alogior:
2515 a |= next;
2516 break;
2517 case Alogxor:
2518 a ^= next;
2519 break;
2520 case Amax:
2521 if (!argnum || a < next)
2522 a = next;
2523 break;
2524 case Amin:
2525 if (!argnum || next < a)
2526 a = next;
2527 break;
2482 } 2528 }
2483 break;
2484 case Alogand:
2485 accum &= next;
2486 break;
2487 case Alogior:
2488 accum |= next;
2489 break;
2490 case Alogxor:
2491 accum ^= next;
2492 break;
2493 case Amax:
2494 if (!argnum || next > accum)
2495 accum = next;
2496 break;
2497 case Amin:
2498 if (!argnum || next < accum)
2499 accum = next;
2500 break;
2501 } 2529 }
2530
2531 if (use_float)
2532 return float_arith_driver (accum, argnum, code, nargs, args);
2533
2534 accum = a;
2502 } 2535 }
2503 2536
2504 XSETINT (val, accum); 2537 return make_fixnum_or_float (accum);
2505 return val;
2506} 2538}
2507 2539
2508#undef isnan 2540#undef isnan
@@ -2777,7 +2809,8 @@ Markers are converted to integers. */)
2777 2809
2778 if (FLOATP (number)) 2810 if (FLOATP (number))
2779 return (make_float (1.0 + XFLOAT_DATA (number))); 2811 return (make_float (1.0 + XFLOAT_DATA (number)));
2780 2812 if (XINT (number) + 1 == MOST_POSITIVE_FIXNUM + 1)
2813 return make_float (XINT (number) + 1);
2781 XSETINT (number, XINT (number) + 1); 2814 XSETINT (number, XINT (number) + 1);
2782 return number; 2815 return number;
2783} 2816}
@@ -2791,7 +2824,8 @@ Markers are converted to integers. */)
2791 2824
2792 if (FLOATP (number)) 2825 if (FLOATP (number))
2793 return (make_float (-1.0 + XFLOAT_DATA (number))); 2826 return (make_float (-1.0 + XFLOAT_DATA (number)));
2794 2827 if (XINT (number) - 1 == MOST_NEGATIVE_FIXNUM - 1)
2828 return make_float (XINT (number) - 1);
2795 XSETINT (number, XINT (number) - 1); 2829 XSETINT (number, XINT (number) - 1);
2796 return number; 2830 return number;
2797} 2831}