From 32bdbece9ff928f7d06e2e3d9c99f740b12689d4 Mon Sep 17 00:00:00 2001 From: Peter Bex Date: Sat, 20 Jun 2015 20:55:23 +0200 Subject: [PATCH] Avoid shifting signed values, which is undefined behaviour in C. --- chicken.h | 12 ++++++------ runtime.c | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/chicken.h b/chicken.h index 8f8d82e..66c276a 100644 --- a/chicken.h +++ b/chicken.h @@ -864,7 +864,7 @@ DECL_C_PROC_p0 (128, 1,0,0,0,0,0,0,0) /* This is word-size dependent: */ #ifdef C_SIXTY_FOUR # define C_align(n) C_align8(n) -# define C_wordstobytes(n) ((n) << 3) +# define C_wordstobytes(n) ((C_uword)(n) << 3) # define C_bytestowords(n) (((n) + 7) >> 3) # define C_wordsperdouble(n) (n) # define C_WORD_MIN LONG_MIN @@ -872,9 +872,9 @@ DECL_C_PROC_p0 (128, 1,0,0,0,0,0,0,0) # define C_UWORD_MAX ULONG_MAX #else # define C_align(n) C_align4(n) -# define C_wordstobytes(n) ((n) << 2) +# define C_wordstobytes(n) ((C_uword)(n) << 2) # define C_bytestowords(n) (((n) + 3) >> 2) -# define C_wordsperdouble(n) ((n) << 1) +# define C_wordsperdouble(n) ((C_uword)(n) << 1) # define C_WORD_MIN INT_MIN # define C_WORD_MAX INT_MAX # define C_UWORD_MAX UINT_MAX @@ -1086,7 +1086,7 @@ DECL_C_PROC_p0 (128, 1,0,0,0,0,0,0,0) #endif #define C_stack_pointer_test ((C_word *)C_alloca(1)) #define C_demand_2(n) (((C_word *)C_fromspace_top + (n)) < (C_word *)C_fromspace_limit) -#define C_fix(n) (((C_word)(n) << C_FIXNUM_SHIFT) | C_FIXNUM_BIT) +#define C_fix(n) ((C_word)((C_uword)(n) << C_FIXNUM_SHIFT) | C_FIXNUM_BIT) #define C_unfix(x) C_CHECKp(x,C_fixnump(C_VAL1(x)),((C_VAL1(x)) >> C_FIXNUM_SHIFT)) #define C_make_character(c) (((((C_uword)(c)) & C_CHAR_BIT_MASK) << C_CHAR_SHIFT) | C_CHARACTER_BITS) #define C_character_code(x) C_CHECKp(x,C_charp(C_VAL1(x)),((C_word)(C_VAL1(x)) >> C_CHAR_SHIFT) & C_CHAR_BIT_MASK) @@ -1102,7 +1102,7 @@ DECL_C_PROC_p0 (128, 1,0,0,0,0,0,0,0) #define C_mk_nbool(x) ((x) ? C_SCHEME_FALSE : C_SCHEME_TRUE) #define C_port_file(p) C_CHECKp(p,C_portp(C_VAL1(p)),(C_FILEPTR)C_block_item(C_VAL1(p), 0)) #define C_data_pointer(b) C_CHECKp(b,C_blockp((C_word)C_VAL1(b)),(void *)(((C_SCHEME_BLOCK *)(C_VAL1(b)))->data)) -#define C_fitsinfixnump(n) (((n) & C_INT_SIGN_BIT) == (((n) & C_INT_TOP_BIT) << 1)) +#define C_fitsinfixnump(n) (((n) & C_INT_SIGN_BIT) == ((C_uword)((n) & C_INT_TOP_BIT) << 1)) #define C_ufitsinfixnump(n) (((n) & (C_INT_SIGN_BIT | (C_INT_SIGN_BIT >> 1))) == 0) #define C_quickflonumtruncate(n) (C_fix((C_word)C_flonum_magnitude(n))) #define C_and(x, y) (C_truep(x) ? (y) : C_SCHEME_FALSE) @@ -1220,7 +1220,7 @@ DECL_C_PROC_p0 (128, 1,0,0,0,0,0,0,0) #define C_fixnum_or(n1, n2) (C_u_fixnum_or(n1, n2) | C_FIXNUM_BIT) #define C_fixnum_xor(n1, n2) (((n1) ^ (n2)) | C_FIXNUM_BIT) #define C_fixnum_not(n) ((~(n)) | C_FIXNUM_BIT) -#define C_fixnum_shift_left(n1, n2) (C_fix(C_unfix(n1) << C_unfix(n2))) +#define C_fixnum_shift_left(n1, n2) (C_fix(((C_uword)C_unfix(n1) << (C_uword)C_unfix(n2)))) #define C_fixnum_shift_right(n1, n2) (((n1) >> C_unfix(n2)) | C_FIXNUM_BIT) #define C_u_fixnum_negate(n) (-(n) + 2 * C_FIXNUM_BIT) #define C_fixnum_negate(n) (C_u_fixnum_negate(n) | C_FIXNUM_BIT) diff --git a/runtime.c b/runtime.c index 75ca654..f592f93 100644 --- a/runtime.c +++ b/runtime.c @@ -218,7 +218,7 @@ extern void _C_do_apply_hack(void *proc, C_word *args, int count) C_noret; #define is_fptr(x) (((x) & C_GC_FORWARDING_BIT) != 0) #define ptr_to_fptr(x) ((((x) >> FORWARDING_BIT_SHIFT) & 1) | C_GC_FORWARDING_BIT | ((x) & ~1)) -#define fptr_to_ptr(x) (((x) << FORWARDING_BIT_SHIFT) | ((x) & ~(C_GC_FORWARDING_BIT | 1))) +#define fptr_to_ptr(x) (((C_uword)(x) << FORWARDING_BIT_SHIFT) | ((x) & ~(C_GC_FORWARDING_BIT | 1))) #define C_check_flonum(x, w) if(C_immediatep(x) || C_block_header(x) != C_FLONUM_TAG) \ barf(C_BAD_ARGUMENT_TYPE_NO_FLONUM_ERROR, w, x); @@ -5316,7 +5316,7 @@ C_regparm C_word C_fcall C_a_i_arithmetic_shift(C_word **a, int c, C_word n1, C_ if(sgn < 0) { if(s < 0) nn >>= -s; - else nn <<= s; + else nn = (C_word)((C_uword)nn << s); if(C_fitsinfixnump(nn)) return C_fix(nn); else return C_flonum(a, nn); @@ -7633,7 +7633,7 @@ C_regparm C_word C_fcall convert_string_to_number(C_char *str, int radix, C_word return 0; } - else if((n & C_INT_SIGN_BIT) != ((n << 1) & C_INT_SIGN_BIT)) { /* doesn't fit into fixnum? */ + else if((n & C_INT_SIGN_BIT) != (((C_uword)n << 1) & C_INT_SIGN_BIT)) { /* doesn't fit into fixnum? */ if(*eptr == '\0' || !C_strncmp(eptr, ".0", C_strlen(eptr))) { *flo = (double)n; return 2; @@ -7943,7 +7943,7 @@ void C_ccall C_peek_signed_integer(C_word c, C_word closure, C_word k, C_word v, C_word x = C_block_item(v, C_unfix(index)); C_alloc_flonum; - if((x & C_INT_SIGN_BIT) != ((x << 1) & C_INT_SIGN_BIT)) { + if((x & C_INT_SIGN_BIT) != (((C_uword)x << 1) & C_INT_SIGN_BIT)) { C_kontinue_flonum(k, (double)x); } @@ -7956,7 +7956,7 @@ void C_ccall C_peek_unsigned_integer(C_word c, C_word closure, C_word k, C_word C_word x = C_block_item(v, C_unfix(index)); C_alloc_flonum; - if((x & C_INT_SIGN_BIT) || ((x << 1) & C_INT_SIGN_BIT)) { + if((x & C_INT_SIGN_BIT) || (((C_uword)x << 1) & C_INT_SIGN_BIT)) { C_kontinue_flonum(k, (double)(C_uword)x); } @@ -8845,10 +8845,10 @@ static C_regparm C_word C_fcall decode_literal2(C_word **ptr, C_char **str, return (C_word)(*(*str - 1)); case C_FIXNUM_BIT: - val = *((*str)++) << 24; /* always big endian */ - val |= (*((*str)++) & 0xff) << 16; - val |= (*((*str)++) & 0xff) << 8; - val |= (*((*str)++) & 0xff); + val = (C_uword)*((*str)++) << 24; /* always big endian */ + val |= ((C_uword)*((*str)++) & 0xff) << 16; + val |= ((C_uword)*((*str)++) & 0xff) << 8; + val |= ((C_uword)*((*str)++) & 0xff); return C_fix(val); #ifdef C_SIXTY_FOUR -- 2.1.4