From c1f1cd08ae1564e79ba84a61b278440384a9912f Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 25 Apr 2024 14:15:20 -0400 Subject: [PATCH 1/6] fix `_checked_mul_dims` fixes https://github.com/JuliaLang/julia/issues/54244. --- base/boot.jl | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/base/boot.jl b/base/boot.jl index a3c5c03bdf721..b5a124007f732 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -562,19 +562,21 @@ function _checked_mul_dims(m::Int, n::Int) return a, ovflw end function _checked_mul_dims(m::Int, d::Int...) - @_foldable_meta # the compiler needs to know this loop terminates - a = m - i = 1 - ovflw = false - while Intrinsics.sle_int(i, nfields(d)) - di = getfield(d, i) - b = Intrinsics.checked_smul_int(a, di) - ovflw = Intrinsics.or_int(ovflw, getfield(b, 2)) - ovflw = Intrinsics.or_int(ovflw, Intrinsics.ule_int(typemax_Int, di)) - a = getfield(b, 1) - i = Intrinsics.add_int(i, 1) + @_foldable_meta # the compiler needs to know this loop terminates + a = m + i = 1 + ovflw = false + zero = a === 0 + while Intrinsics.sle_int(i, nfields(d)) + di = getfield(d, i) + b = Intrinsics.checked_smul_int(a, di) + zero = Intrinsics.or_int(zero, di === 0) + ovflw = Intrinsics.or_int(ovflw, getfield(b, 2)) + ovflw = Intrinsics.or_int(ovflw, Intrinsics.ule_int(typemax_Int, di)) + a = getfield(b, 1) + i = Intrinsics.add_int(i, 1) end - return a, ovflw + return a, Intrinsics.and_int(ovflw, Intrinsics.not_int(zero)) end # convert a set of dims to a length, with overflow checking From aa9c362cb7105936139c669c1ba216a377aef0c7 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 25 Apr 2024 14:25:09 -0400 Subject: [PATCH 2/6] tests for #54244 --- test/core.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/core.jl b/test/core.jl index ed1e1fc6757d2..888561b429dcd 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7213,6 +7213,16 @@ end @test_throws ArgumentError Array{Int, 2}(undef, -10, 0) @test_throws ArgumentError Array{Int, 2}(undef, -1, -1) +# issue #54244 +# test that zero sized array doesn't throw even with large axes +bignum = Int==Int64 ? 2^32 : 2^16 +Array{Int}(undef, 0, bignum, bignum) +Array{Int}(undef, bignum, bignum, 0) +Array{Int}(undef, bignum, bignum, 0, bignum, bignum) +# but also test that it does throw if the axes multiply to a multiple of typemax(UInt) +@test_throws ArgumentError Array{Int, 2}(undef, bignum, bignum) +@test_throws ArgumentError Array{Int, 2}(undef, 1, bignum, bignum) + # issue #28812 @test Tuple{Vararg{Array{T} where T,3}} === Tuple{Array,Array,Array} From 0823f89887faceb52558b231e64636a4ae3239a7 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 25 Apr 2024 16:11:26 -0400 Subject: [PATCH 3/6] fix negative sizes --- base/boot.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/base/boot.jl b/base/boot.jl index b5a124007f732..16820aa070369 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -566,17 +566,18 @@ function _checked_mul_dims(m::Int, d::Int...) a = m i = 1 ovflw = false - zero = a === 0 + neg = Intrinsics.ule_int(typemax_Int, m) + zero = false # if m==0 we won't have overflow since we go left to right while Intrinsics.sle_int(i, nfields(d)) di = getfield(d, i) b = Intrinsics.checked_smul_int(a, di) zero = Intrinsics.or_int(zero, di === 0) ovflw = Intrinsics.or_int(ovflw, getfield(b, 2)) - ovflw = Intrinsics.or_int(ovflw, Intrinsics.ule_int(typemax_Int, di)) + neg = Intrinsics.or_int(neg, Intrinsics.ule_int(typemax_Int, di)) a = getfield(b, 1) i = Intrinsics.add_int(i, 1) end - return a, Intrinsics.and_int(ovflw, Intrinsics.not_int(zero)) + return a, Intrinsics.or_int(neg, Intrinsics.and_int(ovflw, Intrinsics.not_int(zero))) end # convert a set of dims to a length, with overflow checking From a18e6faadeb6fe1e7acd3057ff2982ecf72bcad1 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 25 Apr 2024 16:14:54 -0400 Subject: [PATCH 4/6] more tests --- test/core.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/core.jl b/test/core.jl index 888561b429dcd..41816956771ed 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7222,6 +7222,10 @@ Array{Int}(undef, bignum, bignum, 0, bignum, bignum) # but also test that it does throw if the axes multiply to a multiple of typemax(UInt) @test_throws ArgumentError Array{Int, 2}(undef, bignum, bignum) @test_throws ArgumentError Array{Int, 2}(undef, 1, bignum, bignum) +# also test that we always throw erros for negative dims even if other dims are 0 or the product is positive +@test_throws ArgumentError Array{Int, 2}(undef, 0, -4, -4) +@test_throws ArgumentError Array{Int, 2}(undef, -4, 1, 0) +@test_throws ArgumentError Array{Int, 2}(undef, -4, -4, 1) # issue #28812 @test Tuple{Vararg{Array{T} where T,3}} === Tuple{Array,Array,Array} From 357af49d0b82123dc588d9aa9d4217d5674513c2 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 25 Apr 2024 16:17:41 -0400 Subject: [PATCH 5/6] whitespace --- test/core.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core.jl b/test/core.jl index 41816956771ed..f5f9556333c6b 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7215,7 +7215,7 @@ end # issue #54244 # test that zero sized array doesn't throw even with large axes -bignum = Int==Int64 ? 2^32 : 2^16 +bignum = Int==Int64 ? 2^32 : 2^16 Array{Int}(undef, 0, bignum, bignum) Array{Int}(undef, bignum, bignum, 0) Array{Int}(undef, bignum, bignum, 0, bignum, bignum) From 0629ec6c75ce3217b1a21d65b88e21097e627200 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 25 Apr 2024 17:50:51 -0400 Subject: [PATCH 6/6] fix tests. --- test/core.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/core.jl b/test/core.jl index f5f9556333c6b..c908a9c2b5afd 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7220,12 +7220,12 @@ Array{Int}(undef, 0, bignum, bignum) Array{Int}(undef, bignum, bignum, 0) Array{Int}(undef, bignum, bignum, 0, bignum, bignum) # but also test that it does throw if the axes multiply to a multiple of typemax(UInt) -@test_throws ArgumentError Array{Int, 2}(undef, bignum, bignum) -@test_throws ArgumentError Array{Int, 2}(undef, 1, bignum, bignum) +@test_throws ArgumentError Array{Int}(undef, bignum, bignum) +@test_throws ArgumentError Array{Int}(undef, 1, bignum, bignum) # also test that we always throw erros for negative dims even if other dims are 0 or the product is positive -@test_throws ArgumentError Array{Int, 2}(undef, 0, -4, -4) -@test_throws ArgumentError Array{Int, 2}(undef, -4, 1, 0) -@test_throws ArgumentError Array{Int, 2}(undef, -4, -4, 1) +@test_throws ArgumentError Array{Int}(undef, 0, -4, -4) +@test_throws ArgumentError Array{Int}(undef, -4, 1, 0) +@test_throws ArgumentError Array{Int}(undef, -4, -4, 1) # issue #28812 @test Tuple{Vararg{Array{T} where T,3}} === Tuple{Array,Array,Array}