~ chicken-core (chicken-5) 52c702a9291e7287f28e9dc47958bb6608925545
commit 52c702a9291e7287f28e9dc47958bb6608925545
Author: Peter Bex <peter@more-magic.net>
AuthorDate: Sun May 21 18:54:38 2017 +0200
Commit: Evan Hanson <evhan@foldling.org>
CommitDate: Thu May 25 09:51:00 2017 +1200
In the scrutinizer, do not assume big fixnums will fit into 32 bits
When the scrutinizer applies a specialization for a fixnum, it should
make sure it really is a fixnum. If compiling on a 64-bit platform, a
fixnum literal might no longer be a fixnum when the program is running
on a 32-bit platform.
Thus, we check whether the literal is a big-fixnum? first.
Unfortunately, we can't do the converse in CHICKEN 4: when compiling on
a 32-bit platform, a "big fixnum" literal will always be read in as a
flonum. However, this will result in consistent behaviour when
compiling the resulting C code on 32-bit or 64-bit.
Signed-off-by: Evan Hanson <evhan@foldling.org>
diff --git a/NEWS b/NEWS
index c23bcf1e..7e395acc 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,10 @@
- Build system
- Fixed broken compilation on NetBSD, due to missing _NETBSD_SOURCE.
+- Compiler
+ - The scrutinizer no longer uses 'fixnum as the type for fixnums
+ that might not fit into a fixnum on 32-bit architectures.
+
4.12.0
diff --git a/lfa2.scm b/lfa2.scm
index 2a5fd526..20c9fe6a 100644
--- a/lfa2.scm
+++ b/lfa2.scm
@@ -159,13 +159,10 @@
;; a simplified variant of the one in scrutinizer.scm
(cond ((string? lit) 'string)
((symbol? lit) 'symbol)
+ ;; Do not assume fixnum width matches target platforms!
+ ((big-fixnum? lit) 'number)
((fixnum? lit) 'fixnum)
((flonum? lit) 'float)
- ((number? lit)
- (case number-type
- ((fixnum) 'fixnum)
- ((flonum) 'flonum)
- (else 'number)))
((boolean? lit) 'boolean)
((null? lit) 'null)
((list? lit) 'list)
diff --git a/scrutinizer.scm b/scrutinizer.scm
index ad7856ff..9720ea0d 100644
--- a/scrutinizer.scm
+++ b/scrutinizer.scm
@@ -163,13 +163,10 @@
(define (constant-result lit)
(cond ((string? lit) 'string)
((symbol? lit) 'symbol)
+ ;; Do not assume fixnum width matches target platforms!
+ ((big-fixnum? lit) 'number)
((fixnum? lit) 'fixnum)
((flonum? lit) 'float)
- ((number? lit)
- (case number-type
- ((fixnum) 'fixnum)
- ((flonum) 'flonum)
- (else 'number))) ; in case...
((boolean? lit)
(if lit 'true 'false))
((null? lit) 'null)
diff --git a/tests/typematch-tests.scm b/tests/typematch-tests.scm
index 4d841ce8..149252a4 100644
--- a/tests/typematch-tests.scm
+++ b/tests/typematch-tests.scm
@@ -353,3 +353,22 @@
(compiler-typecase 1
(number #t)
(fixnum #f)))
+
+;; Always a fixnum
+(assert
+ (compiler-typecase #x3fffffff
+ (float #f)
+ (fixnum #t)))
+
+;; Is a fixnum on 64-bit, flonum on 32-bit. The best we can do is to
+;; check for 'number (on 32-bits it will always be a float)
+(assert
+ (compiler-typecase #x4fffffff
+ (fixnum #f)
+ (number #t)))
+
+;; Always a flonum
+(assert
+ (compiler-typecase #x7fffffffffffffff
+ (fixnum #f)
+ (float #t)))
Trap