~ 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