diff options
author | Mark H Weaver <mhw@netris.org> | 2013-07-14 14:47:10 -0400 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2013-07-14 14:47:10 -0400 |
commit | 7e8166f5bdb526c021c826943aaf050134cccc83 (patch) | |
tree | 06bc43dba78bbc17c4a0f9bb6780bb188f2aca37 /libguile/vm-i-scheme.c | |
parent | e8f329972666db6c9d4644619473e14d54db3a80 (diff) | |
download | guile-7e8166f5bdb526c021c826943aaf050134cccc83.tar.gz |
Fix VM 'ash' for right shifts by large amounts.
Fixes <http://bugs.gnu.org/14864>.
Reported by Göran Weinholt <goran@weinholt.se>.
* libguile/vm-i-scheme.c (ash): Fallback to 'scm_ash' for right shifts
with counts >= SCM_I_FIXNUM_BIT, since '>>' is not guaranteed to work
correctly for large counts.
Diffstat (limited to 'libguile/vm-i-scheme.c')
-rw-r--r-- | libguile/vm-i-scheme.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/libguile/vm-i-scheme.c b/libguile/vm-i-scheme.c index b85d980fd..7402cc1a7 100644 --- a/libguile/vm-i-scheme.c +++ b/libguile/vm-i-scheme.c @@ -388,8 +388,12 @@ VM_DEFINE_FUNCTION (159, ash, "ash", 2) if (SCM_I_INUMP (x) && SCM_I_INUMP (y)) { if (SCM_I_INUM (y) < 0) - /* Right shift, will be a fixnum. */ - RETURN (SCM_I_MAKINUM (SCM_I_INUM (x) >> -SCM_I_INUM (y))); + { + /* Right shift, will be a fixnum. */ + if (SCM_I_INUM (y) > -SCM_I_FIXNUM_BIT) + RETURN (SCM_I_MAKINUM (SCM_I_INUM (x) >> -SCM_I_INUM (y))); + /* fall through */ + } else /* Left shift. See comments in scm_ash. */ { |