diff options
| author | Paul Eggert | 2025-11-27 10:38:53 -0800 |
|---|---|---|
| committer | Paul Eggert | 2025-11-27 10:47:56 -0800 |
| commit | 9b4d9bb01e5f93ac0060aaa2579f687e9157ef4a (patch) | |
| tree | a6c65f8abcb5e27d2cdf22d6207a611a05412b91 /src/data.c | |
| parent | e576dc7556994b3fb76bc0092ec828c0026de327 (diff) | |
| download | emacs-9b4d9bb01e5f93ac0060aaa2579f687e9157ef4a.tar.gz emacs-9b4d9bb01e5f93ac0060aaa2579f687e9157ef4a.zip | |
Fix recently-introduced ash bug
Problem reported by John Paul Adrian Glaubitz (bug#79876).
* src/data.c (Fash): Don’t assume stdc_leading_zeros, which
returns an unsigned integer of unspecified width, returns
a value narrower than EMACS_INT. Also, don’t munge the code to
worry about stdc_leading_zeros (0); unlike GCC’s __builtin_clz,
stdc_leading_zeros works fine on 0. And use a temporary to
avoid a cast.
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/src/data.c b/src/data.c index fb9e1e3218d..a1861bd53d0 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -3532,10 +3532,10 @@ discarding bits. */) | |||
| 3532 | CHECK_INTEGER (value); | 3532 | CHECK_INTEGER (value); |
| 3533 | CHECK_INTEGER (count); | 3533 | CHECK_INTEGER (count); |
| 3534 | 3534 | ||
| 3535 | if (BASE_EQ (value, make_fixnum (0))) | ||
| 3536 | return value; | ||
| 3537 | if (! FIXNUMP (count)) | 3535 | if (! FIXNUMP (count)) |
| 3538 | { | 3536 | { |
| 3537 | if (BASE_EQ (value, make_fixnum (0))) | ||
| 3538 | return value; | ||
| 3539 | if (mpz_sgn (*xbignum_val (count)) < 0) | 3539 | if (mpz_sgn (*xbignum_val (count)) < 0) |
| 3540 | { | 3540 | { |
| 3541 | EMACS_INT v = (FIXNUMP (value) ? XFIXNUM (value) | 3541 | EMACS_INT v = (FIXNUMP (value) ? XFIXNUM (value) |
| @@ -3563,8 +3563,9 @@ discarding bits. */) | |||
| 3563 | else if (FIXNUMP (value)) | 3563 | else if (FIXNUMP (value)) |
| 3564 | { | 3564 | { |
| 3565 | EMACS_INT v = XFIXNUM (value); | 3565 | EMACS_INT v = XFIXNUM (value); |
| 3566 | if (stdc_leading_zeros ((EMACS_UINT)(v < 0 ? ~v : v)) - c | 3566 | EMACS_UINT uv = v < 0 ? ~v : v; |
| 3567 | >= EMACS_INT_WIDTH - FIXNUM_BITS + 1) | 3567 | EMACS_INT lz = stdc_leading_zeros (uv); |
| 3568 | if (EMACS_INT_WIDTH - FIXNUM_BITS < lz - c) | ||
| 3568 | return make_fixnum (v << c); | 3569 | return make_fixnum (v << c); |
| 3569 | } | 3570 | } |
| 3570 | 3571 | ||