~ chicken-core (chicken-5) e5c7d96dd9c8cb9160fa8601b4c9d0c0c457ce7f
commit e5c7d96dd9c8cb9160fa8601b4c9d0c0c457ce7f Author: Peter Bex <peter@more-magic.net> AuthorDate: Sat Jun 20 21:04:01 2015 +0200 Commit: Christian Kellermann <ckeen@pestilenz.org> CommitDate: Thu Jun 25 09:35:11 2015 +0200 Avoid shifting signed values, which is undefined behaviour in C. Signed-off-by: Christian Kellermann <ckeen@pestilenz.org> diff --git a/chicken.h b/chicken.h index f53fb3de..c0f437c2 100644 --- a/chicken.h +++ b/chicken.h @@ -910,7 +910,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 @@ -918,9 +918,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 @@ -1134,7 +1134,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) @@ -1155,7 +1155,7 @@ DECL_C_PROC_p0 (128, 1,0,0,0,0,0,0,0) #define C_fitsinbignumhalfdigitp(n)(C_BIGNUM_DIGIT_HI_HALF(n) == 0) #define C_bignum_negated_fitsinfixnump(b) (C_bignum_size(b) == 1 && (C_bignum_negativep(b) ? C_ufitsinfixnump(*C_bignum_digits(b)) : !(*C_bignum_digits(b) & C_INT_SIGN_BIT) && C_fitsinfixnump(-(C_word)*C_bignum_digits(b)))) #define C_bignum_mutate_size(b, s) (C_block_header(C_internal_bignum_vector(b)) = (C_STRING_TYPE | C_wordstobytes((s)+1))) -#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_and(x, y) (C_truep(x) ? (y) : C_SCHEME_FALSE) #define C_c_bytevector(x) ((unsigned char *)C_data_pointer(x)) @@ -1284,7 +1284,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) /* XXX TODO OBSOLETE, but still used by C_fixnum_negate, which is fxneg */ #define C_u_fixnum_negate(n) (-(n) + 2 * C_FIXNUM_BIT) @@ -2561,7 +2561,7 @@ C_inline C_s64 C_num_to_int64(C_word x) } else if (C_truep(C_bignump(x))) { C_s64 num = C_bignum_digits(x)[0]; #ifndef C_SIXTY_FOUR - if (C_bignum_size(x) > 1) num |= ((C_s64)C_bignum_digits(x)[1]) << 32; + if (C_bignum_size(x) > 1) num |= (C_s64)(((C_u64)C_bignum_digits(x)[1]) << 32); #endif if (C_bignum_negativep(x)) return -num; else return num; @@ -3068,7 +3068,7 @@ C_inline C_word C_i_fixnum_bit_setp(C_word n, C_word i) } else { i = C_unfix(i); if (i >= C_WORD_SIZE) return C_mk_bool(n & C_INT_SIGN_BIT); - else return C_mk_bool((C_unfix(n) & ((C_word)1 << i)) != 0); + else return C_mk_bool((C_unfix(n) & (C_word)((C_uword)1 << i)) != 0); } } diff --git a/runtime.c b/runtime.c index 63938969..ce2d80fa 100644 --- a/runtime.c +++ b/runtime.c @@ -244,7 +244,7 @@ extern void _C_do_apply_hack(void *proc, C_word *args, int count) C_noret; #define free_tmp_bignum(b) C_free((void *)(b)) #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_real(x, w, v) if(((x) & C_FIXNUM_BIT) != 0) v = C_unfix(x); \ else if(C_immediatep(x) || C_block_header(x) != C_FLONUM_TAG) \ @@ -2583,7 +2583,7 @@ C_regparm C_word C_fcall C_static_bignum(C_word **ptr, int len, C_char *str) negp = ((*str++) == '-') ? 1 : 0; --len; } - size = C_BIGNUM_BITS_TO_DIGITS(len << 2); + size = C_BIGNUM_BITS_TO_DIGITS((unsigned int)len << 2); dptr = (C_word *)C_malloc(C_wordstobytes(C_SIZEOF_INTERNAL_BIGNUM_VECTOR(size))); if(dptr == NULL) @@ -6337,7 +6337,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); @@ -6374,7 +6374,7 @@ C_s_a_i_arithmetic_shift(C_word **ptr, C_word n, C_word x, C_word y) } else if (y > 0 && y < C_WORD_SIZE-2 && /* After shifting, the length still fits a fixnum */ (C_ilen(C_unfix(x)) + y) < C_WORD_SIZE-2) { - return C_fix(C_unfix(x) << y); + return C_fix((C_uword)C_unfix(x) << y); } else { x = C_a_u_i_fix_to_big(&a, x); } @@ -7829,7 +7829,7 @@ bignum_times_bignum_karatsuba(C_word **ptr, C_word x, C_word y, C_word negp) /* top(x) = a << (bits - 1) and bottom(y) = ((b + (a - c)) << bits) + b */ bits = C_unfix(n) * C_BIGNUM_DIGIT_LENGTH; - x = o[i++] = C_s_a_i_arithmetic_shift(&ka, 2, a, C_fix(bits << 1)); + x = o[i++] = C_s_a_i_arithmetic_shift(&ka, 2, a, C_fix((C_uword)bits << 1)); c = o[i++] = C_s_a_u_i_integer_minus(&ka, 2, a, c); c = o[i++] = C_s_a_u_i_integer_plus(&ka, 2, b, c); c = o[i++] = C_s_a_i_arithmetic_shift(&ka, 2, c, C_fix(bits)); @@ -9306,8 +9306,8 @@ C_regparm double C_fcall C_bignum_to_double(C_word bignum) C_uword *start = C_bignum_digits(bignum), *scan = start + C_bignum_size(bignum); while (start < scan) { - accumulator *= (C_word)1 << C_BIGNUM_HALF_DIGIT_LENGTH; - accumulator *= (C_word)1 << C_BIGNUM_HALF_DIGIT_LENGTH; + accumulator *= (C_uword)1 << C_BIGNUM_HALF_DIGIT_LENGTH; + accumulator *= (C_uword)1 << C_BIGNUM_HALF_DIGIT_LENGTH; accumulator += (*--scan); } return(C_bignum_negativep(bignum) ? -accumulator : accumulator); @@ -10358,9 +10358,9 @@ bignum_destructive_divide_normalized(C_word big_u, C_word big_v, C_word big_q) rhat = hat % vn_1; /* Two whiles is faster than one big check with an OR. Thanks, Gauche! */ - while(qhat >= (1L << C_BIGNUM_HALF_DIGIT_LENGTH)) { qhat--; rhat += vn_1; } + while(qhat >= (1UL << C_BIGNUM_HALF_DIGIT_LENGTH)) { qhat--; rhat += vn_1; } while(qhat * vn_2 > C_BIGNUM_DIGIT_COMBINE(rhat, C_uhword_ref(u, j+n-2)) - && rhat < (1L << C_BIGNUM_HALF_DIGIT_LENGTH)) { + && rhat < (1UL << C_BIGNUM_HALF_DIGIT_LENGTH)) { qhat--; rhat += vn_1; } @@ -11043,7 +11043,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; @@ -11265,7 +11265,7 @@ bignum_to_str_2(C_word c, C_word self, C_word string) assert(index >= buf); radix_digit = big_digit; big_digit = *scan++; - radix_digit |= (big_digit << big_digit_len) & radix_mask; + radix_digit |= ((unsigned int)big_digit << big_digit_len) & radix_mask; big_digit >>= (radix_shift - big_digit_len); big_digit_len = C_BIGNUM_DIGIT_LENGTH - big_digit_len; } @@ -12413,10 +12413,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_FOURTrap