diff options
| author | Paul Eggert | 2017-03-04 23:14:52 -0800 |
|---|---|---|
| committer | Paul Eggert | 2017-03-04 23:18:39 -0800 |
| commit | 0d55c44a9a00da3b8542e92586654adeb2bcf228 (patch) | |
| tree | 1105e60b43ef80d105ca613ece1c8cfc6ee64f07 /src | |
| parent | 44e7ee2e356452139156e8175c46f646835d27ff (diff) | |
| download | emacs-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.c | 45 | ||||
| -rw-r--r-- | src/dbusbind.c | 4 | ||||
| -rw-r--r-- | src/fileio.c | 13 | ||||
| -rw-r--r-- | src/sound.c | 8 |
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. */ | ||
| 2559 | uintmax_t | 2558 | uintmax_t |
| 2560 | cons_to_unsigned (Lisp_Object c, uintmax_t max) | 2559 | cons_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. */ | ||
| 2612 | intmax_t | 2612 | intmax_t |
| 2613 | cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) | 2613 | cons_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 |