>> I noticed make check has been failing for salmonella since 2012-12-24 >> (see http://tests.call-cc.org/master/linux/x86/2012/12/). > > Thanks for pointing this out, it was not a known issue. The problem is > due to a regression test I've added for Felix's patch on the conversion > of unsigned-integer64 types. > > The real question is: what should happen? Shouldn't all 64-bit > quantities be automatically converted from double to "long long" or > whatever it's called on 32 bit platforms? The same will happen on > 64 bit platforms when using 63 or 64-bit numbers. Maybe the regression > test should catch that, too.
Attached is a patch that corrects the behaviour of C_i_foreign_[unsigned]_integer64_argumentp (there where bugs in both the signed and unsigned variant). I've disabled the test you added for 32-bit platforms - integer64 as return- or argument-type is only partially useful on 32-bit systems (in fact, it is mostly useless on all platforms, but we avoid compiler warnings and at least check and convert the values properly). cheers, felix
>From 6bbaf6266ead65e286eef31e95d0801b9193c656 Mon Sep 17 00:00:00 2001 From: felix <[email protected]> Date: Fri, 28 Dec 2012 00:13:27 +0100 Subject: [PATCH] Corrected behaviour for "C_i_foreign_[unsigned]_integer64_argumentp" Extract floating-point values from argument and compare with MIN/MAX for the associated C type). Added limits to chicken.h, which uses stdint.h now (or inttypes.h on SunOS). Disabled compiler-test added by Peter for #955 for 32-bit platforms. --- chicken.h | 55 ++++++++++++++++++++++++++++++++++++---------- runtime.c | 11 ++++++-- tests/compiler-tests.scm | 1 + 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/chicken.h b/chicken.h index e128332..082c318 100644 --- a/chicken.h +++ b/chicken.h @@ -502,9 +502,17 @@ static inline int isinf_ld (long double x) #define C_F32_LOCATIVE 8 #define C_F64_LOCATIVE 9 +#if defined (__MINGW32__) +# define C_s64 __int64 +# define C_u64 unsigned __int64 +#else +# define C_s64 int64_t +# define C_u64 uint64_t +#endif + #ifdef C_SIXTY_FOUR # ifdef C_LLP -# define C_word __int64 +# define C_word C_s64 # else # define C_word long # endif @@ -516,24 +524,47 @@ static inline int isinf_ld (long double x) # define C_s32 int #endif -#if defined (__MINGW32__) -# define C_s64 __int64 -# define C_u64 unsigned __int64 -#else -# define C_s64 int64_t -# define C_u64 uint64_t -#endif - #define C_char char #define C_uchar unsigned C_char #define C_byte char #define C_uword unsigned C_word #define C_header C_uword +#if defined(__sun__) && !defined(__svr4__) +/* SunOS is supposed not to have stdint.h */ +# include <inttypes.h> +#else +# include <stdint.h> +#endif + +/* if all else fails, use these: + #define UINT64_MAX (18446744073709551615ULL) + #define INT64_MAX (9223372036854775807LL) + #define INT64_MIN (-INT64_MAX - 1) + #define UINT32_MAX (4294967295U) + #define INT32_MAX (2147483647) + #define INT32_MIN (-INT32_MAX - 1) + #define UINT16_MAX (65535U) + #define INT16_MAX (32767) + #define INT16_MIN (-INT16_MAX - 1) + #define UINT8_MAX (255) + #define INT8_MAX (127) + #define INT8_MIN (-INT8_MAX - 1) +*/ + +#define C_U64_MAX UINT64_MAX +#define C_S64_MIN INT64_MIN +#define C_S64_MAX INT64_MAX + #if defined(C_LLP) && defined(C_SIXTY_FOUR) -# define C_long __int64 -# define C_LONG_MAX LONG_LONG_MAX -# define C_LONG_MIN LONG_LONG_MIN +# define C_long C_s64 +# ifndef LONG_LONG_MAX +# define C_LONG_MAX LLONG_MAX +# define C_LONG_MIN LLONG_MIN +# else +# define C_LONG_MAX LONG_LONG_MAX +# define C_LONG_MIN LONG_LONG_MIN +# endif #else # define C_long long # define C_LONG_MAX LONG_MAX diff --git a/runtime.c b/runtime.c index 7da117d..a09dfb9 100644 --- a/runtime.c +++ b/runtime.c @@ -5881,8 +5881,13 @@ C_regparm C_word C_fcall C_i_foreign_integer64_argumentp(C_word x) { double m; - if((x & C_FIXNUM_BIT) != 0 || (!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG)) - return x; + if((x & C_FIXNUM_BIT) != 0) return x; + + if(!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG) { + m = C_flonum_magnitude(x); + + if(m >= C_S64_MIN && m <= C_S64_MAX) return x; + } barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, NULL, x); return C_SCHEME_UNDEFINED; @@ -5915,7 +5920,7 @@ C_regparm C_word C_fcall C_i_foreign_unsigned_integer64_argumentp(C_word x) if(!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG) { m = C_flonum_magnitude(x); - if(m >= 0 && m <= C_UWORD_MAX) return x; + if(m >= 0 && m <= C_U64_MAX) return x; } barf(C_BAD_ARGUMENT_TYPE_NO_UINTEGER_ERROR, NULL, x); diff --git a/tests/compiler-tests.scm b/tests/compiler-tests.scm index c858042..4c26dc7 100644 --- a/tests/compiler-tests.scm +++ b/tests/compiler-tests.scm @@ -235,6 +235,7 @@ (string->number "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0"))) ;; #955: unsigned-integer64 arg returned magnitude instead of Scheme object. +#+64bit (assert (= #xAB54A98CEB1F0AD2 ((foreign-lambda* unsigned-integer64 ((unsigned-integer64 x)) "C_return(x);") -- 1.7.0.4
_______________________________________________ Chicken-hackers mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/chicken-hackers
