Skip to content

Commit effff39

Browse files
committed
check integer truncation (#5413) and make more operators follow T+T => T (#3759)
the sysimg builds, but still need to: - check same-size signed<->unsigned conversion - make tests pass
1 parent 79ce765 commit effff39

File tree

4 files changed

+51
-164
lines changed

4 files changed

+51
-164
lines changed

base/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ all: pcre_h.jl errno_h.jl build_h.jl.phony fenv_constants.jl file_constants.jl u
1616

1717
pcre_h.jl:
1818
ifeq ($(USE_SYSTEM_PCRE), 1)
19-
@$(call PRINT_PERL, $(CPP) -dM $(shell $(PCRE_CONFIG) --prefix)/include/pcre.h | perl -nle '/^\s*#define\s+PCRE_(\w*)\s*\(?($(PCRE_CONST))\)?\s*$$/ and print "const $$1 = uint32($$2)"' | sort > $@)
19+
@$(call PRINT_PERL, $(CPP) -dM $(shell $(PCRE_CONFIG) --prefix)/include/pcre.h | perl -nle '/^\s*#define\s+PCRE_(\w*)\s*\(?($(PCRE_CONST))\)?\s*$$/ and print "const $$1 = int32($$2)"' | sort > $@)
2020
else
21-
@$(call PRINT_PERL, $(CPP) -dM $(build_includedir)/pcre.h | perl -nle '/^\s*#define\s+PCRE_(\w*)\s*\(?($(PCRE_CONST))\)?\s*$$/ and print "const $$1 = uint32($$2)"' | sort > $@)
21+
@$(call PRINT_PERL, $(CPP) -dM $(build_includedir)/pcre.h | perl -nle '/^\s*#define\s+PCRE_(\w*)\s*\(?($(PCRE_CONST))\)?\s*$$/ and print "const $$1 = int32($$2)"' | sort > $@)
2222
endif
2323

2424
errno_h.jl:

base/dict.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ function deserialize{K,V}(s, T::Type{Dict{K,V}})
385385
return t
386386
end
387387

388-
hashindex(key, sz) = (int(hash(key)) & (sz-1)) + 1
388+
hashindex(key, sz) = (reinterpret(Int,hash(key)) & (sz-1)) + 1
389389

390390
isslotempty(h::Dict, i::Int) = h.slots[i] == 0x0
391391
isslotfilled(h::Dict, i::Int) = h.slots[i] == 0x1

base/int.jl

+47-160
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,20 @@ end
1010

1111
## integer arithmetic ##
1212

13-
-(x::SmallSigned) = -int(x)
14-
-(x::SmallUnsigned) = -uint(x)
15-
16-
+{T<:SmallSigned}(x::T, y::T) = int(x) + int(y)
17-
-{T<:SmallSigned}(x::T, y::T) = int(x) - int(y)
18-
*{T<:SmallSigned}(x::T, y::T) = int(x) * int(y)
19-
20-
+{T<:SmallUnsigned}(x::T, y::T) = uint(x) + uint(y)
21-
-{T<:SmallUnsigned}(x::T, y::T) = uint(x) - uint(y)
22-
*{T<:SmallUnsigned}(x::T, y::T) = uint(x) * uint(y)
23-
24-
-(x::Int) = box(Int,neg_int(unbox(Int,x)))
25-
-(x::Uint) = box(Uint,neg_int(unbox(Uint,x)))
26-
-(x::Int64) = box(Int64,neg_int(unbox(Int64,x)))
27-
-(x::Uint64) = box(Uint64,neg_int(unbox(Uint64,x)))
28-
-(x::Int128) = box(Int128,neg_int(unbox(Int128,x)))
29-
-(x::Uint128) = box(Uint128,neg_int(unbox(Uint128,x)))
30-
31-
+(x::Int, y::Int) = box(Int,add_int(unbox(Int,x),unbox(Int,y)))
32-
+(x::Uint, y::Uint) = box(Uint,add_int(unbox(Uint,x),unbox(Uint,y)))
33-
+(x::Int64, y::Int64) = box(Int64,add_int(unbox(Int64,x),unbox(Int64,y)))
34-
+(x::Uint64, y::Uint64) = box(Uint64,add_int(unbox(Uint64,x),unbox(Uint64,y)))
35-
+(x::Int128, y::Int128) = box(Int128,add_int(unbox(Int128,x),unbox(Int128,y)))
36-
+(x::Uint128, y::Uint128) = box(Uint128,add_int(unbox(Uint128,x),unbox(Uint128,y)))
37-
38-
-(x::Int, y::Int) = box(Int,sub_int(unbox(Int,x),unbox(Int,y)))
39-
-(x::Uint, y::Uint) = box(Uint,sub_int(unbox(Uint,x),unbox(Uint,y)))
40-
-(x::Int64, y::Int64) = box(Int64,sub_int(unbox(Int64,x),unbox(Int64,y)))
41-
-(x::Uint64, y::Uint64) = box(Uint64,sub_int(unbox(Uint64,x),unbox(Uint64,y)))
42-
-(x::Int128, y::Int128) = box(Int128,sub_int(unbox(Int128,x),unbox(Int128,y)))
43-
-(x::Uint128, y::Uint128) = box(Uint128,sub_int(unbox(Uint128,x),unbox(Uint128,y)))
44-
45-
*(x::Int, y::Int) = box(Int,mul_int(unbox(Int,x),unbox(Int,y)))
46-
*(x::Uint, y::Uint) = box(Uint,mul_int(unbox(Uint,x),unbox(Uint,y)))
47-
*(x::Int64, y::Int64) = box(Int64,mul_int(unbox(Int64,x),unbox(Int64,y)))
48-
*(x::Uint64, y::Uint64) = box(Uint64,mul_int(unbox(Uint64,x),unbox(Uint64,y)))
13+
const IntTypes = (Int8, Uint8, Int16, Uint16, Int32, Uint32,
14+
Int64, Uint64, Int128, Uint128)
15+
16+
+(x::Int, y::Int) = box(Int,add_int(unbox(Int,x),unbox(Int,y)))
17+
<(x::Int, y::Int) = slt_int(unbox(Int,x),unbox(Int,y))
18+
19+
for T in IntTypes
20+
@eval begin
21+
-(x::$T) = box($T,neg_int(unbox($T,x)))
22+
+(x::$T, y::$T) = box($T, add_int(unbox($T,x),unbox($T,y)))
23+
-(x::$T, y::$T) = box($T, sub_int(unbox($T,x),unbox($T,y)))
24+
*(x::$T, y::$T) = box($T, mul_int(unbox($T,x),unbox($T,y)))
25+
end
26+
end
4927

5028
/(x::Integer, y::Integer) = float(x)/float(y)
5129
inv(x::Integer) = float(one(x))/float(x)
@@ -113,89 +91,19 @@ cld{T<:Integer }(x::T, y::T) = div(x,y)+(!signbit(x$y)&(rem(x,y)!=0))
11391

11492
## integer bitwise operations ##
11593

116-
~(x::Int8 ) = box(Int8,not_int(unbox(Int8,x)))
117-
~(x::Int16) = box(Int16,not_int(unbox(Int16,x)))
118-
~(x::Int32) = box(Int32,not_int(unbox(Int32,x)))
119-
~(x::Int64) = box(Int64,not_int(unbox(Int64,x)))
120-
~(x::Int128) = box(Int128,not_int(unbox(Int128,x)))
121-
122-
~(x::Uint8 ) = box(Uint8,not_int(unbox(Uint8,x)))
123-
~(x::Uint16) = box(Uint16,not_int(unbox(Uint16,x)))
124-
~(x::Uint32) = box(Uint32,not_int(unbox(Uint32,x)))
125-
~(x::Uint64) = box(Uint64,not_int(unbox(Uint64,x)))
126-
~(x::Uint128) = box(Uint128,not_int(unbox(Uint128,x)))
127-
128-
(&)(x::Int8, y::Int8 ) = box(Int8,and_int(unbox(Int8,x),unbox(Int8,y)))
129-
(&)(x::Int16, y::Int16) = box(Int16,and_int(unbox(Int16,x),unbox(Int16,y)))
130-
(&)(x::Int32, y::Int32) = box(Int32,and_int(unbox(Int32,x),unbox(Int32,y)))
131-
(&)(x::Int64, y::Int64) = box(Int64,and_int(unbox(Int64,x),unbox(Int64,y)))
132-
(&)(x::Int128, y::Int128) = box(Int128,and_int(unbox(Int128,x),unbox(Int128,y)))
133-
134-
(&)(x::Uint8, y::Uint8 ) = box(Uint8,and_int(unbox(Uint8,x),unbox(Uint8,y)))
135-
(&)(x::Uint16, y::Uint16) = box(Uint16,and_int(unbox(Uint16,x),unbox(Uint16,y)))
136-
(&)(x::Uint32, y::Uint32) = box(Uint32,and_int(unbox(Uint32,x),unbox(Uint32,y)))
137-
(&)(x::Uint64, y::Uint64) = box(Uint64,and_int(unbox(Uint64,x),unbox(Uint64,y)))
138-
(&)(x::Uint128, y::Uint128) = box(Uint128,and_int(unbox(Uint128,x),unbox(Uint128,y)))
139-
140-
|(x::Int8, y::Int8) = box(Int8,or_int(unbox(Int8,x),unbox(Int8,y)))
141-
|(x::Int16, y::Int16) = box(Int16,or_int(unbox(Int16,x),unbox(Int16,y)))
142-
|(x::Int32, y::Int32) = box(Int32,or_int(unbox(Int32,x),unbox(Int32,y)))
143-
|(x::Int64, y::Int64) = box(Int64,or_int(unbox(Int64,x),unbox(Int64,y)))
144-
|(x::Int128, y::Int128) = box(Int128,or_int(unbox(Int128,x),unbox(Int128,y)))
145-
146-
|(x::Uint8, y::Uint8) = box(Uint8,or_int(unbox(Uint8,x),unbox(Uint8,y)))
147-
|(x::Uint16, y::Uint16) = box(Uint16,or_int(unbox(Uint16,x),unbox(Uint16,y)))
148-
|(x::Uint32, y::Uint32) = box(Uint32,or_int(unbox(Uint32,x),unbox(Uint32,y)))
149-
|(x::Uint64, y::Uint64) = box(Uint64,or_int(unbox(Uint64,x),unbox(Uint64,y)))
150-
|(x::Uint128, y::Uint128) = box(Uint128,or_int(unbox(Uint128,x),unbox(Uint128,y)))
151-
152-
($)(x::Int8, y::Int8) = box(Int8,xor_int(unbox(Int8,x),unbox(Int8,y)))
153-
($)(x::Int16, y::Int16) = box(Int16,xor_int(unbox(Int16,x),unbox(Int16,y)))
154-
($)(x::Int32, y::Int32) = box(Int32,xor_int(unbox(Int32,x),unbox(Int32,y)))
155-
($)(x::Int64, y::Int64) = box(Int64,xor_int(unbox(Int64,x),unbox(Int64,y)))
156-
($)(x::Int128, y::Int128) = box(Int128,xor_int(unbox(Int128,x),unbox(Int128,y)))
157-
158-
($)(x::Uint8, y::Uint8) = box(Uint8,xor_int(unbox(Uint8,x),unbox(Uint8,y)))
159-
($)(x::Uint16, y::Uint16) = box(Uint16,xor_int(unbox(Uint16,x),unbox(Uint16,y)))
160-
($)(x::Uint32, y::Uint32) = box(Uint32,xor_int(unbox(Uint32,x),unbox(Uint32,y)))
161-
($)(x::Uint64, y::Uint64) = box(Uint64,xor_int(unbox(Uint64,x),unbox(Uint64,y)))
162-
($)(x::Uint128, y::Uint128) = box(Uint128,xor_int(unbox(Uint128,x),unbox(Uint128,y)))
163-
164-
<<(x::Int8, y::Int32) = box(Int8,shl_int(unbox(Int8,x),unbox(Int32,y)))
165-
<<(x::Int16, y::Int32) = box(Int16,shl_int(unbox(Int16,x),unbox(Int32,y)))
166-
<<(x::Int32, y::Int32) = box(Int32,shl_int(unbox(Int32,x),unbox(Int32,y)))
167-
<<(x::Int64, y::Int32) = box(Int64,shl_int(unbox(Int64,x),unbox(Int32,y)))
168-
<<(x::Int128, y::Int32) = box(Int128,shl_int(unbox(Int128,x),unbox(Int32,y)))
169-
170-
<<(x::Uint8, y::Int32) = box(Uint8,shl_int(unbox(Uint8,x),unbox(Int32,y)))
171-
<<(x::Uint16, y::Int32) = box(Uint16,shl_int(unbox(Uint16,x),unbox(Int32,y)))
172-
<<(x::Uint32, y::Int32) = box(Uint32,shl_int(unbox(Int32,x),unbox(Uint32,y)))
173-
<<(x::Uint64, y::Int32) = box(Uint64,shl_int(unbox(Uint64,x),unbox(Int32,y)))
174-
<<(x::Uint128, y::Int32) = box(Uint128,shl_int(unbox(Uint128,x),unbox(Int32,y)))
175-
176-
>>(x::Int8, y::Int32) = box(Int8,ashr_int(unbox(Int8,x),unbox(Int32,y)))
177-
>>(x::Int16, y::Int32) = box(Int16,ashr_int(unbox(Int16,x),unbox(Int32,y)))
178-
>>(x::Int32, y::Int32) = box(Int32,ashr_int(unbox(Int32,x),unbox(Int32,y)))
179-
>>(x::Int64, y::Int32) = box(Int64,ashr_int(unbox(Int64,x),unbox(Int32,y)))
180-
>>(x::Int128, y::Int32) = box(Int128,ashr_int(unbox(Int128,x),unbox(Int32,y)))
181-
182-
>>(x::Uint8, y::Int32) = box(Uint8,lshr_int(unbox(Uint8,x),unbox(Int32,y)))
183-
>>(x::Uint16, y::Int32) = box(Uint16,lshr_int(unbox(Uint16,x),unbox(Int32,y)))
184-
>>(x::Uint32, y::Int32) = box(Uint32,lshr_int(unbox(Int32,x),unbox(Uint32,y)))
185-
>>(x::Uint64, y::Int32) = box(Uint64,lshr_int(unbox(Uint64,x),unbox(Int32,y)))
186-
>>(x::Uint128, y::Int32) = box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))
187-
188-
>>>(x::Int8, y::Int32) = box(Int8,lshr_int(unbox(Int8,x),unbox(Int32,y)))
189-
>>>(x::Int16, y::Int32) = box(Int16,lshr_int(unbox(Int16,x),unbox(Int32,y)))
190-
>>>(x::Int32, y::Int32) = box(Int32,lshr_int(unbox(Int32,x),unbox(Int32,y)))
191-
>>>(x::Int64, y::Int32) = box(Int64,lshr_int(unbox(Int64,x),unbox(Int32,y)))
192-
>>>(x::Int128, y::Int32) = box(Int128,lshr_int(unbox(Int128,x),unbox(Int32,y)))
193-
194-
>>>(x::Uint8, y::Int32) = box(Uint8,lshr_int(unbox(Uint8,x),unbox(Int32,y)))
195-
>>>(x::Uint16, y::Int32) = box(Uint16,lshr_int(unbox(Uint16,x),unbox(Int32,y)))
196-
>>>(x::Uint32, y::Int32) = box(Uint32,lshr_int(unbox(Int32,x),unbox(Uint32,y)))
197-
>>>(x::Uint64, y::Int32) = box(Uint64,lshr_int(unbox(Uint64,x),unbox(Int32,y)))
198-
>>>(x::Uint128, y::Int32) = box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))
94+
for T in IntTypes
95+
@eval begin
96+
~(x::$T) = box($T,not_int(unbox($T,x)))
97+
98+
(&)(x::$T, y::$T) = box($T,and_int(unbox($T,x),unbox($T,y)))
99+
(|)(x::$T, y::$T) = box($T, or_int(unbox($T,x),unbox($T,y)))
100+
($)(x::$T, y::$T) = box($T,xor_int(unbox($T,x),unbox($T,y)))
101+
102+
<<(x::$T, y::Int32) = box($T, shl_int(unbox($T,x),unbox(Int32,y)))
103+
>>(x::$T, y::Int32) = box($T,ashr_int(unbox($T,x),unbox(Int32,y)))
104+
>>>(x::$T, y::Int32) = box($T,lshr_int(unbox($T,x),unbox(Int32,y)))
105+
end
106+
end
199107

200108
bswap(x::Int8) = x
201109
bswap(x::Uint8) = x
@@ -208,39 +116,13 @@ bswap(x::Uint64) = box(Uint64,bswap_int(unbox(Uint64,x)))
208116
bswap(x::Int128) = box(Int128,bswap_int(unbox(Int128,x)))
209117
bswap(x::Uint128) = box(Uint128,bswap_int(unbox(Uint128,x)))
210118

211-
count_ones(x::Int8) = int(box(Int8,ctpop_int(unbox(Int8,x))))
212-
count_ones(x::Uint8) = int(box(Uint8,ctpop_int(unbox(Uint8,x))))
213-
count_ones(x::Int16) = int(box(Int16,ctpop_int(unbox(Int16,x))))
214-
count_ones(x::Uint16) = int(box(Uint16,ctpop_int(unbox(Uint16,x))))
215-
count_ones(x::Int32) = int(box(Int32,ctpop_int(unbox(Int32,x))))
216-
count_ones(x::Uint32) = int(box(Uint32,ctpop_int(unbox(Uint32,x))))
217-
count_ones(x::Int64) = int(box(Int64,ctpop_int(unbox(Int64,x))))
218-
count_ones(x::Uint64) = int(box(Uint64,ctpop_int(unbox(Uint64,x))))
219-
count_ones(x::Int128) = int(box(Int128,ctpop_int(unbox(Int128,x))))
220-
count_ones(x::Uint128) = int(box(Uint128,ctpop_int(unbox(Uint128,x))))
221-
222-
leading_zeros(x::Int8) = int(box(Int8,ctlz_int(unbox(Int8,x))))
223-
leading_zeros(x::Uint8) = int(box(Uint8,ctlz_int(unbox(Uint8,x))))
224-
leading_zeros(x::Int16) = int(box(Int16,ctlz_int(unbox(Int16,x))))
225-
leading_zeros(x::Uint16) = int(box(Uint16,ctlz_int(unbox(Uint16,x))))
226-
leading_zeros(x::Int32) = int(box(Int32,ctlz_int(unbox(Int32,x))))
227-
leading_zeros(x::Uint32) = int(box(Uint32,ctlz_int(unbox(Uint32,x))))
228-
leading_zeros(x::Int64) = int(box(Int64,ctlz_int(unbox(Int64,x))))
229-
leading_zeros(x::Uint64) = int(box(Uint64,ctlz_int(unbox(Uint64,x))))
230-
leading_zeros(x::Int128) = int(box(Int128,ctlz_int(unbox(Int128,x))))
231-
leading_zeros(x::Uint128) = int(box(Uint128,ctlz_int(unbox(Uint128,x))))
232-
233-
trailing_zeros(x::Int8) = int(box(Int8,cttz_int(unbox(Int8,x))))
234-
trailing_zeros(x::Uint8) = int(box(Uint8,cttz_int(unbox(Uint8,x))))
235-
trailing_zeros(x::Int16) = int(box(Int16,cttz_int(unbox(Int16,x))))
236-
trailing_zeros(x::Uint16) = int(box(Uint16,cttz_int(unbox(Uint16,x))))
237-
trailing_zeros(x::Int32) = int(box(Int32,cttz_int(unbox(Int32,x))))
238-
trailing_zeros(x::Uint32) = int(box(Uint32,cttz_int(unbox(Uint32,x))))
239-
trailing_zeros(x::Int64) = int(box(Int64,cttz_int(unbox(Int64,x))))
240-
trailing_zeros(x::Uint64) = int(box(Uint64,cttz_int(unbox(Uint64,x))))
241-
trailing_zeros(x::Int128) = int(box(Int128,cttz_int(unbox(Int128,x))))
242-
trailing_zeros(x::Uint128) = int(box(Uint128,cttz_int(unbox(Uint128,x))))
243-
119+
for T in IntTypes
120+
@eval begin
121+
count_ones(x::$T) = int(box($T,ctpop_int(unbox($T,x))))
122+
leading_zeros(x::$T) = int(box($T,ctlz_int(unbox($T,x))))
123+
trailing_zeros(x::$T) = int(box($T,cttz_int(unbox($T,x))))
124+
end
125+
end
244126
count_zeros (x::Integer) = count_ones(~x)
245127
leading_ones (x::Integer) = leading_zeros(~x)
246128
trailing_ones(x::Integer) = trailing_zeros(~x)
@@ -284,9 +166,14 @@ const _inttypes = (Bool, Int8, Uint8, Int16, Uint16, Int32, Uint32, Char,
284166
Int64, Uint64, Int128, Uint128)
285167

286168
for to in _inttypes, from in _inttypes
287-
if !(to===from) && !(to===Bool)
169+
if !(to === from) && !(to === Bool)
288170
if to.size < from.size
289-
@eval convert(::Type{$to}, x::($from)) = box($to,trunc_int($to,unbox($from,x)))
171+
if issubtype(to, Signed)
172+
@eval convert(::Type{$to}, x::($from)) = box($to,checked_trunc_sint($to,unbox($from,x)))
173+
else
174+
@eval convert(::Type{$to}, x::($from)) = box($to,checked_trunc_uint($to,unbox($from,x)))
175+
end
176+
@eval itrunc(::Type{$to}, x::($from)) = box($to,trunc_int($to,unbox($from,x)))
290177
elseif from.size < to.size || from===Bool
291178
if issubtype(from, Signed)
292179
@eval convert(::Type{$to}, x::($from)) = box($to,sext_int($to,unbox($from,x)))
@@ -402,9 +289,9 @@ const WORD_SIZE = int(Int.size)*8
402289

403290
## integer promotions ##
404291

405-
promote_rule(::Type{Int16}, ::Type{Int8} ) = Int
406-
promote_rule(::Type{Int32}, ::Type{Int8} ) = Int
407-
promote_rule(::Type{Int32}, ::Type{Int16}) = Int
292+
promote_rule(::Type{Int16}, ::Type{Int8} ) = Int16
293+
promote_rule(::Type{Int32}, ::Type{Int8} ) = Int32
294+
promote_rule(::Type{Int32}, ::Type{Int16}) = Int32
408295
promote_rule(::Type{Int64}, ::Type{Int8} ) = Int64
409296
promote_rule(::Type{Int64}, ::Type{Int16}) = Int64
410297
promote_rule(::Type{Int64}, ::Type{Int32}) = Int64
@@ -413,9 +300,9 @@ promote_rule(::Type{Int128}, ::Type{Int16}) = Int128
413300
promote_rule(::Type{Int128}, ::Type{Int32}) = Int128
414301
promote_rule(::Type{Int128}, ::Type{Int64}) = Int128
415302

416-
promote_rule(::Type{Uint16}, ::Type{Uint8} ) = Uint
417-
promote_rule(::Type{Uint32}, ::Type{Uint8} ) = Uint
418-
promote_rule(::Type{Uint32}, ::Type{Uint16}) = Uint
303+
promote_rule(::Type{Uint16}, ::Type{Uint8} ) = Uint16
304+
promote_rule(::Type{Uint32}, ::Type{Uint8} ) = Uint32
305+
promote_rule(::Type{Uint32}, ::Type{Uint16}) = Uint32
419306
promote_rule(::Type{Uint64}, ::Type{Uint8} ) = Uint64
420307
promote_rule(::Type{Uint64}, ::Type{Uint16}) = Uint64
421308
promote_rule(::Type{Uint64}, ::Type{Uint32}) = Uint64

base/string.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ const memhash = Uint == Uint64 ? :memhash_seed : :memhash32_seed
660660

661661
function hash{T<:ByteString}(s::Union(T,SubString{T}), h::Uint)
662662
h += uint(0x71e729fd56419c81)
663-
ccall(memhash, Uint, (Ptr{Uint8}, Csize_t, Uint32), s, sizeof(s), h) + h
663+
ccall(memhash, Uint, (Ptr{Uint8}, Csize_t, Uint32), s, sizeof(s), itrunc(Uint32,h)) + h
664664
end
665665
hash(s::String, h::Uint) = hash(bytestring(s), h)
666666

0 commit comments

Comments
 (0)