aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2017-03-04 23:14:52 -0800
committerPaul Eggert2017-03-04 23:18:39 -0800
commit0d55c44a9a00da3b8542e92586654adeb2bcf228 (patch)
tree1105e60b43ef80d105ca613ece1c8cfc6ee64f07 /src
parent44e7ee2e356452139156e8175c46f646835d27ff (diff)
downloademacs-0d55c44a9a00da3b8542e92586654adeb2bcf228.tar.gz
emacs-0d55c44a9a00da3b8542e92586654adeb2bcf228.zip
Compare and round more carefully
* etc/NEWS: Document this. * src/data.c (store_symval_forwarding): * src/sound.c (parse_sound): Do not botch NaN comparison. * src/data.c (cons_to_unsigned, cons_to_signed): Signal an error if a floating-point arg is not integral. * src/data.c (cons_to_unsigned, cons_to_signed): * src/fileio.c (file_offset): Use simpler overflow check. * src/dbusbind.c (xd_extract_signed, xd_extract_unsigned): Avoid rounding error in overflow check. (Fcar_less_than_car): Use arithcompare directly. * test/src/charset-tests.el: New file.
Diffstat (limited to 'src')
-rw-r--r--src/data.c45
-rw-r--r--src/dbusbind.c4
-rw-r--r--src/fileio.c13
-rw-r--r--src/sound.c8
4 files changed, 35 insertions, 35 deletions
diff --git a/src/data.c b/src/data.c
index 88d86697e42..66f4c9c738d 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1110,10 +1110,8 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
1110 else if ((prop = Fget (predicate, Qrange), !NILP (prop))) 1110 else if ((prop = Fget (predicate, Qrange), !NILP (prop)))
1111 { 1111 {
1112 Lisp_Object min = XCAR (prop), max = XCDR (prop); 1112 Lisp_Object min = XCAR (prop), max = XCDR (prop);
1113 1113 if (! NUMBERP (newval)
1114 if (!NUMBERP (newval) 1114 || NILP (CALLN (Fleq, min, newval, max)))
1115 || !NILP (arithcompare (newval, min, ARITH_LESS))
1116 || !NILP (arithcompare (newval, max, ARITH_GRTR)))
1117 wrong_range (min, max, newval); 1115 wrong_range (min, max, newval);
1118 } 1116 }
1119 else if (FUNCTIONP (predicate)) 1117 else if (FUNCTIONP (predicate))
@@ -2554,12 +2552,13 @@ uintbig_to_lisp (uintmax_t i)
2554} 2552}
2555 2553
2556/* Convert the cons-of-integers, integer, or float value C to an 2554/* Convert the cons-of-integers, integer, or float value C to an
2557 unsigned value with maximum value MAX. Signal an error if C does not 2555 unsigned value with maximum value MAX, where MAX is one less than a
2558 have a valid format or is out of range. */ 2556 power of 2. Signal an error if C does not have a valid format or
2557 is out of range. */
2559uintmax_t 2558uintmax_t
2560cons_to_unsigned (Lisp_Object c, uintmax_t max) 2559cons_to_unsigned (Lisp_Object c, uintmax_t max)
2561{ 2560{
2562 bool valid = 0; 2561 bool valid = false;
2563 uintmax_t val; 2562 uintmax_t val;
2564 if (INTEGERP (c)) 2563 if (INTEGERP (c))
2565 { 2564 {
@@ -2569,11 +2568,10 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max)
2569 else if (FLOATP (c)) 2568 else if (FLOATP (c))
2570 { 2569 {
2571 double d = XFLOAT_DATA (c); 2570 double d = XFLOAT_DATA (c);
2572 if (0 <= d 2571 if (0 <= d && d < 1.0 + max)
2573 && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1))
2574 { 2572 {
2575 val = d; 2573 val = d;
2576 valid = 1; 2574 valid = val == d;
2577 } 2575 }
2578 } 2576 }
2579 else if (CONSP (c) && NATNUMP (XCAR (c))) 2577 else if (CONSP (c) && NATNUMP (XCAR (c)))
@@ -2587,7 +2585,7 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max)
2587 { 2585 {
2588 uintmax_t mid = XFASTINT (XCAR (rest)); 2586 uintmax_t mid = XFASTINT (XCAR (rest));
2589 val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); 2587 val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest));
2590 valid = 1; 2588 valid = true;
2591 } 2589 }
2592 else if (top <= UINTMAX_MAX >> 16) 2590 else if (top <= UINTMAX_MAX >> 16)
2593 { 2591 {
@@ -2596,37 +2594,38 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max)
2596 if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) 2594 if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16)
2597 { 2595 {
2598 val = top << 16 | XFASTINT (rest); 2596 val = top << 16 | XFASTINT (rest);
2599 valid = 1; 2597 valid = true;
2600 } 2598 }
2601 } 2599 }
2602 } 2600 }
2603 2601
2604 if (! (valid && val <= max)) 2602 if (! (valid && val <= max))
2605 error ("Not an in-range integer, float, or cons of integers"); 2603 error ("Not an in-range integer, integral float, or cons of integers");
2606 return val; 2604 return val;
2607} 2605}
2608 2606
2609/* Convert the cons-of-integers, integer, or float value C to a signed 2607/* Convert the cons-of-integers, integer, or float value C to a signed
2610 value with extrema MIN and MAX. Signal an error if C does not have 2608 value with extrema MIN and MAX. MAX should be one less than a
2611 a valid format or is out of range. */ 2609 power of 2, and MIN should be zero or the negative of a power of 2.
2610 Signal an error if C does not have a valid format or is out of
2611 range. */
2612intmax_t 2612intmax_t
2613cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) 2613cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
2614{ 2614{
2615 bool valid = 0; 2615 bool valid = false;
2616 intmax_t val; 2616 intmax_t val;
2617 if (INTEGERP (c)) 2617 if (INTEGERP (c))
2618 { 2618 {
2619 val = XINT (c); 2619 val = XINT (c);
2620 valid = 1; 2620 valid = true;
2621 } 2621 }
2622 else if (FLOATP (c)) 2622 else if (FLOATP (c))
2623 { 2623 {
2624 double d = XFLOAT_DATA (c); 2624 double d = XFLOAT_DATA (c);
2625 if (min <= d 2625 if (min <= d && d < 1.0 + max)
2626 && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1))
2627 { 2626 {
2628 val = d; 2627 val = d;
2629 valid = 1; 2628 valid = val == d;
2630 } 2629 }
2631 } 2630 }
2632 else if (CONSP (c) && INTEGERP (XCAR (c))) 2631 else if (CONSP (c) && INTEGERP (XCAR (c)))
@@ -2640,7 +2639,7 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
2640 { 2639 {
2641 intmax_t mid = XFASTINT (XCAR (rest)); 2640 intmax_t mid = XFASTINT (XCAR (rest));
2642 val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); 2641 val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest));
2643 valid = 1; 2642 valid = true;
2644 } 2643 }
2645 else if (INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16) 2644 else if (INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16)
2646 { 2645 {
@@ -2649,13 +2648,13 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
2649 if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) 2648 if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16)
2650 { 2649 {
2651 val = top << 16 | XFASTINT (rest); 2650 val = top << 16 | XFASTINT (rest);
2652 valid = 1; 2651 valid = true;
2653 } 2652 }
2654 } 2653 }
2655 } 2654 }
2656 2655
2657 if (! (valid && min <= val && val <= max)) 2656 if (! (valid && min <= val && val <= max))
2658 error ("Not an in-range integer, float, or cons of integers"); 2657 error ("Not an in-range integer, integral float, or cons of integers");
2659 return val; 2658 return val;
2660} 2659}
2661 2660
diff --git a/src/dbusbind.c b/src/dbusbind.c
index e7c3251c14b..d2460fd886e 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -526,7 +526,7 @@ xd_extract_signed (Lisp_Object x, intmax_t lo, intmax_t hi)
526 else 526 else
527 { 527 {
528 double d = XFLOAT_DATA (x); 528 double d = XFLOAT_DATA (x);
529 if (lo <= d && d <= hi) 529 if (lo <= d && d < 1.0 + hi)
530 { 530 {
531 intmax_t n = d; 531 intmax_t n = d;
532 if (n == d) 532 if (n == d)
@@ -554,7 +554,7 @@ xd_extract_unsigned (Lisp_Object x, uintmax_t hi)
554 else 554 else
555 { 555 {
556 double d = XFLOAT_DATA (x); 556 double d = XFLOAT_DATA (x);
557 if (0 <= d && d <= hi) 557 if (0 <= d && d < 1.0 + hi)
558 { 558 {
559 uintmax_t n = d; 559 uintmax_t n = d;
560 if (n == d) 560 if (n == d)
diff --git a/src/fileio.c b/src/fileio.c
index 38400623793..acbf76e0d81 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3426,11 +3426,12 @@ file_offset (Lisp_Object val)
3426 if (FLOATP (val)) 3426 if (FLOATP (val))
3427 { 3427 {
3428 double v = XFLOAT_DATA (val); 3428 double v = XFLOAT_DATA (val);
3429 if (0 <= v 3429 if (0 <= v && v < 1.0 + TYPE_MAXIMUM (off_t))
3430 && (sizeof (off_t) < sizeof v 3430 {
3431 ? v <= TYPE_MAXIMUM (off_t) 3431 off_t o = v;
3432 : v < TYPE_MAXIMUM (off_t))) 3432 if (o == v)
3433 return v; 3433 return o;
3434 }
3434 } 3435 }
3435 3436
3436 wrong_type_argument (intern ("file-offset"), val); 3437 wrong_type_argument (intern ("file-offset"), val);
@@ -5163,7 +5164,7 @@ DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
5163 doc: /* Return t if (car A) is numerically less than (car B). */) 5164 doc: /* Return t if (car A) is numerically less than (car B). */)
5164 (Lisp_Object a, Lisp_Object b) 5165 (Lisp_Object a, Lisp_Object b)
5165{ 5166{
5166 return CALLN (Flss, Fcar (a), Fcar (b)); 5167 return arithcompare (Fcar (a), Fcar (b), ARITH_LESS);
5167} 5168}
5168 5169
5169/* Build the complete list of annotations appropriate for writing out 5170/* Build the complete list of annotations appropriate for writing out
diff --git a/src/sound.c b/src/sound.c
index 84754165db5..4714ac1796b 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -387,14 +387,14 @@ parse_sound (Lisp_Object sound, Lisp_Object *attrs)
387 { 387 {
388 if (INTEGERP (attrs[SOUND_VOLUME])) 388 if (INTEGERP (attrs[SOUND_VOLUME]))
389 { 389 {
390 if (XINT (attrs[SOUND_VOLUME]) < 0 390 EMACS_INT volume = XINT (attrs[SOUND_VOLUME]);
391 || XINT (attrs[SOUND_VOLUME]) > 100) 391 if (! (0 <= volume && volume <= 100))
392 return 0; 392 return 0;
393 } 393 }
394 else if (FLOATP (attrs[SOUND_VOLUME])) 394 else if (FLOATP (attrs[SOUND_VOLUME]))
395 { 395 {
396 if (XFLOAT_DATA (attrs[SOUND_VOLUME]) < 0 396 double volume = XFLOAT_DATA (attrs[SOUND_VOLUME]);
397 || XFLOAT_DATA (attrs[SOUND_VOLUME]) > 1) 397 if (! (0 <= volume && volume <= 1))
398 return 0; 398 return 0;
399 } 399 }
400 else 400 else