diff --git a/Make.inc b/Make.inc index b48726721962d..2f0d52feb99d4 100644 --- a/Make.inc +++ b/Make.inc @@ -929,6 +929,20 @@ else PCRE_CONFIG := $(build_depsbindir)/pcre2-config endif +ifeq ($(USE_SYSTEM_PATCHELF), 1) +PATCHELF := patchelf +else +PATCHELF := $(build_depsbindir)/patchelf +endif + +# On aarch64 and powerpc64le, we assume the page size is 64K. Our binutils linkers +# and such already assume this, but `patchelf` seems to be behind the times. We +# explicitly tell it to use this large page size so that when we rewrite rpaths and +# such, we don't accidentally create incorrectly-aligned sections in our ELF files. +ifneq (,$(filter $(ARCH),aarch64 powerpc64le)) +PATCHELF += --page-size=65536 +endif + # Use ILP64 BLAS interface when building openblas from source on 64-bit architectures ifeq ($(BINARY), 64) ifeq ($(USE_SYSTEM_BLAS), 1) diff --git a/Makefile b/Makefile index 41b6e3f0a8fd8..575f5e3b43f09 100644 --- a/Makefile +++ b/Makefile @@ -269,7 +269,7 @@ endef ifeq (,$(findstring $(OS),FreeBSD WINNT)) julia-base: $(build_libdir)/libgfortran*.$(SHLIB_EXT)* $(build_libdir)/libgfortran*.$(SHLIB_EXT)*: | $(build_libdir) julia-deps - -$(CUSTOM_LD_LIBRARY_PATH) PATH="$(PATH):$(build_depsbindir)" $(JULIAHOME)/contrib/fixup-libgfortran.sh --verbose $(build_libdir) + -$(CUSTOM_LD_LIBRARY_PATH) PATH="$(PATH):$(build_depsbindir)" PATCHELF="$(PATCHELF)" $(JULIAHOME)/contrib/fixup-libgfortran.sh --verbose $(build_libdir) JL_PRIVATE_LIBS-0 += libgfortran libgcc_s libquadmath endif @@ -374,7 +374,6 @@ endif mkdir -p $(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/ $(INSTALL_F) $(JULIAHOME)/contrib/julia.svg $(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/ -touch -c $(DESTDIR)$(datarootdir)/icons/hicolor/ - -gtk-update-icon-cache --ignore-theme-index $(DESTDIR)$(datarootdir)/icons/hicolor/ mkdir -p $(DESTDIR)$(datarootdir)/applications/ $(INSTALL_F) $(JULIAHOME)/contrib/julia.desktop $(DESTDIR)$(datarootdir)/applications/ # Install appdata file @@ -392,7 +391,7 @@ ifneq ($(DARWIN_FRAMEWORK),1) endif else ifneq (,$(findstring $(OS),Linux FreeBSD)) for j in $(JL_TARGETS) ; do \ - patchelf --set-rpath '$$ORIGIN/$(private_libdir_rel):$$ORIGIN/$(libdir_rel)' $(DESTDIR)$(bindir)/$$j; \ + $(PATCHELF) --set-rpath '$$ORIGIN/$(private_libdir_rel):$$ORIGIN/$(libdir_rel)' $(DESTDIR)$(bindir)/$$j; \ done endif @@ -412,15 +411,15 @@ endif endif # On FreeBSD, remove the build's libdir from each library's RPATH ifeq ($(OS),FreeBSD) - $(JULIAHOME)/contrib/fixup-rpath.sh $(build_depsbindir)/patchelf $(DESTDIR)$(libdir) $(build_libdir) - $(JULIAHOME)/contrib/fixup-rpath.sh $(build_depsbindir)/patchelf $(DESTDIR)$(private_libdir) $(build_libdir) - $(JULIAHOME)/contrib/fixup-rpath.sh $(build_depsbindir)/patchelf $(DESTDIR)$(bindir) $(build_libdir) + $(JULIAHOME)/contrib/fixup-rpath.sh "$(PATCHELF)" $(DESTDIR)$(libdir) $(build_libdir) + $(JULIAHOME)/contrib/fixup-rpath.sh "$(PATCHELF)" $(DESTDIR)$(private_libdir) $(build_libdir) + $(JULIAHOME)/contrib/fixup-rpath.sh "$(PATCHELF)" $(DESTDIR)$(bindir) $(build_libdir) # Set libgfortran's RPATH to ORIGIN instead of GCCPATH. It's only libgfortran that # needs to be fixed here, as libgcc_s and libquadmath don't have RPATHs set. If we # don't set libgfortran's RPATH, it won't be able to find its friends on systems # that don't have the exact GCC port installed used for the build. for lib in $(DESTDIR)$(private_libdir)/libgfortran*$(SHLIB_EXT)*; do \ - $(build_depsbindir)/patchelf --set-rpath '$$ORIGIN' $$lib; \ + $(PATCHELF) --set-rpath '$$ORIGIN' $$lib; \ done endif diff --git a/base/intfuncs.jl b/base/intfuncs.jl index e430603defb35..a05b688146599 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -68,7 +68,7 @@ function lcm(a::T, b::T) where T<:Integer if a == 0 return a else - return checked_abs(a * div(b, gcd(b,a))) + return checked_abs(checked_mul(a, div(b, gcd(b,a)))) end end diff --git a/base/regex.jl b/base/regex.jl index 0f5074bf026f8..3154c56cb9712 100644 --- a/base/regex.jl +++ b/base/regex.jl @@ -669,7 +669,7 @@ regex_opts_str(opts) = (isassigned(_regex_opts_str) ? _regex_opts_str[] : init_r # UInt32 to String mapping for some compile options const _regex_opts_str = Ref{ImmutableDict{UInt32,String}}() -init_regex() = _regex_opts_str[] = foldl(0:15, init=ImmutableDict{UInt32,String}()) do d, o +@noinline init_regex() = _regex_opts_str[] = foldl(0:15, init=ImmutableDict{UInt32,String}()) do d, o opt = UInt32(0) str = "" if o & 1 != 0 diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index f8a577e3dea39..d8b154b78b0c7 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -112,6 +112,7 @@ reshape(parent::AbstractArray, shp::Tuple{Union{Integer,OneTo}, Vararg{Union{Int reshape(parent::AbstractArray, dims::Dims) = _reshape(parent, dims) # Allow missing dimensions with Colon(): +reshape(parent::AbstractVector, ::Colon) = parent reshape(parent::AbstractArray, dims::Int...) = reshape(parent, dims) reshape(parent::AbstractArray, dims::Union{Int,Colon}...) = reshape(parent, dims) reshape(parent::AbstractArray, dims::Tuple{Vararg{Union{Int,Colon}}}) = _reshape(parent, _reshape_uncolon(parent, dims)) @@ -220,6 +221,8 @@ dataids(A::ReshapedArray) = dataids(A.parent) d, r = divrem(ind, strds[1]) (_ind2sub_rs(front(ax), tail(strds), r)..., d + first(ax[end])) end +offset_if_vec(i::Integer, axs::Tuple{<:AbstractUnitRange}) = i + first(axs[1]) - 1 +offset_if_vec(i::Integer, axs::Tuple) = i @inline function getindex(A::ReshapedArrayLF, index::Int) @boundscheck checkbounds(A, index) @@ -237,8 +240,9 @@ end end @inline function _unsafe_getindex(A::ReshapedArray{T,N}, indices::Vararg{Int,N}) where {T,N} - i = Base._sub2ind(size(A), indices...) - I = ind2sub_rs(axes(A.parent), A.mi, i) + axp = axes(A.parent) + i = offset_if_vec(Base._sub2ind(size(A), indices...), axp) + I = ind2sub_rs(axp, A.mi, i) _unsafe_getindex_rs(parent(A), I) end @inline _unsafe_getindex_rs(A, i::Integer) = (@inbounds ret = A[i]; ret) @@ -260,7 +264,9 @@ end end @inline function _unsafe_setindex!(A::ReshapedArray{T,N}, val, indices::Vararg{Int,N}) where {T,N} - @inbounds parent(A)[ind2sub_rs(axes(A.parent), A.mi, Base._sub2ind(size(A), indices...))...] = val + axp = axes(A.parent) + i = offset_if_vec(Base._sub2ind(size(A), indices...), axp) + @inbounds parent(A)[ind2sub_rs(axes(A.parent), A.mi, i)...] = val val end diff --git a/base/stream.jl b/base/stream.jl index 7e80e241d2a78..933db06f67fee 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -917,7 +917,7 @@ function readuntil(x::LibuvStream, c::UInt8; keep::Bool=false) return bytes end -uv_write(s::LibuvStream, p::Vector{UInt8}) = uv_write(s, pointer(p), UInt(sizeof(p))) +uv_write(s::LibuvStream, p::Vector{UInt8}) = GC.@preserve p uv_write(s, pointer(p), UInt(sizeof(p))) # caller must have acquired the iolock function uv_write(s::LibuvStream, p::Ptr{UInt8}, n::UInt) @@ -1036,8 +1036,9 @@ function write(s::LibuvStream, b::UInt8) if buf !== nothing iolock_begin() if bytesavailable(buf) + 1 < buf.maxsize + n = write(buf, b) iolock_end() - return write(buf, b) + return n end iolock_end() end diff --git a/base/strings/search.jl b/base/strings/search.jl index 9840944da35df..15d0a968a0226 100644 --- a/base/strings/search.jl +++ b/base/strings/search.jl @@ -34,8 +34,8 @@ function _search(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = return i == n+1 ? 0 : throw(BoundsError(a, i)) end p = pointer(a) - q = ccall(:memchr, Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), p+i-1, b, n-i+1) - q == C_NULL ? 0 : Int(q-p+1) + q = GC.@preserve a ccall(:memchr, Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), p+i-1, b, n-i+1) + return q == C_NULL ? 0 : Int(q-p+1) end function _search(a::ByteArray, b::AbstractChar, i::Integer = 1) @@ -74,8 +74,8 @@ function _rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = return i == n+1 ? 0 : throw(BoundsError(a, i)) end p = pointer(a) - q = ccall(:memrchr, Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), p, b, i) - q == C_NULL ? 0 : Int(q-p+1) + q = GC.@preserve a ccall(:memrchr, Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), p, b, i) + return q == C_NULL ? 0 : Int(q-p+1) end function _rsearch(a::ByteArray, b::AbstractChar, i::Integer = length(a)) diff --git a/base/strings/string.jl b/base/strings/string.jl index a7f4777e594b6..a65e02f7653bc 100644 --- a/base/strings/string.jl +++ b/base/strings/string.jl @@ -87,7 +87,8 @@ codeunit(s::String) = UInt8 @inline function codeunit(s::String, i::Integer) @boundscheck checkbounds(s, i) - GC.@preserve s unsafe_load(pointer(s, i)) + b = GC.@preserve s unsafe_load(pointer(s, i)) + return b end ## comparison ## @@ -112,7 +113,7 @@ typemin(::String) = typemin(String) ## thisind, nextind ## -Base.@propagate_inbounds thisind(s::String, i::Int) = _thisind_str(s, i) +@propagate_inbounds thisind(s::String, i::Int) = _thisind_str(s, i) # s should be String or SubString{String} @inline function _thisind_str(s, i::Int) @@ -133,7 +134,7 @@ Base.@propagate_inbounds thisind(s::String, i::Int) = _thisind_str(s, i) return i end -Base.@propagate_inbounds nextind(s::String, i::Int) = _nextind_str(s, i) +@propagate_inbounds nextind(s::String, i::Int) = _nextind_str(s, i) # s should be String or SubString{String} @inline function _nextind_str(s, i::Int) @@ -251,7 +252,7 @@ getindex(s::String, r::UnitRange{<:Integer}) = s[Int(first(r)):Int(last(r))] j = nextind(s, j) - 1 n = j - i + 1 ss = _string_n(n) - unsafe_copyto!(pointer(ss), pointer(s, i), n) + GC.@preserve s ss unsafe_copyto!(pointer(ss), pointer(s, i), n) return ss end @@ -323,7 +324,7 @@ function repeat(c::Char, r::Integer) n = 4 - (leading_zeros(u | 0xff) >> 3) s = _string_n(n*r) p = pointer(s) - if n == 1 + GC.@preserve s if n == 1 ccall(:memset, Ptr{Cvoid}, (Ptr{UInt8}, Cint, Csize_t), p, u % UInt8, r) elseif n == 2 p16 = reinterpret(Ptr{UInt16}, p) @@ -340,7 +341,7 @@ function repeat(c::Char, r::Integer) unsafe_store!(p, b3, 3i + 3) end elseif n == 4 - p32 = reinterpret(Ptr{UInt32}, pointer(s)) + p32 = reinterpret(Ptr{UInt32}, p) for i = 1:r unsafe_store!(p32, u, i) end @@ -349,11 +350,11 @@ function repeat(c::Char, r::Integer) end function filter(f, s::String) - out = Base.StringVector(sizeof(s)) + out = StringVector(sizeof(s)) offset = 1 for c in s if f(c) - offset += Base.__unsafe_string!(out, c, offset) + offset += __unsafe_string!(out, c, offset) end end resize!(out, offset-1) diff --git a/base/strings/substring.jl b/base/strings/substring.jl index a83c5d17d9e18..cfebe9991eb7f 100644 --- a/base/strings/substring.jl +++ b/base/strings/substring.jl @@ -51,7 +51,11 @@ convert(::Type{SubString{S}}, s::AbstractString) where {S<:AbstractString} = SubString(convert(S, s)) convert(::Type{T}, s::T) where {T<:SubString} = s -String(s::SubString{String}) = unsafe_string(pointer(s.string, s.offset+1), s.ncodeunits) +function String(s::SubString{String}) + parent = s.string + copy = GC.@preserve parent unsafe_string(pointer(parent, s.offset+1), s.ncodeunits) + return copy +end ncodeunits(s::SubString) = s.ncodeunits codeunit(s::SubString) = codeunit(s.string) @@ -151,25 +155,27 @@ end string(a::String) = String(a) string(a::SubString{String}) = String(a) -@inline function __unsafe_string!(out, c::Char, offs::Integer) +@inline function __unsafe_string!(out, c::Char, offs::Integer) # out is a (new) String (or StringVector) x = bswap(reinterpret(UInt32, c)) n = ncodeunits(c) - unsafe_store!(pointer(out, offs), x % UInt8) - n == 1 && return n - x >>= 8 - unsafe_store!(pointer(out, offs+1), x % UInt8) - n == 2 && return n - x >>= 8 - unsafe_store!(pointer(out, offs+2), x % UInt8) - n == 3 && return n - x >>= 8 - unsafe_store!(pointer(out, offs+3), x % UInt8) + GC.@preserve out begin + unsafe_store!(pointer(out, offs), x % UInt8) + n == 1 && return n + x >>= 8 + unsafe_store!(pointer(out, offs+1), x % UInt8) + n == 2 && return n + x >>= 8 + unsafe_store!(pointer(out, offs+2), x % UInt8) + n == 3 && return n + x >>= 8 + unsafe_store!(pointer(out, offs+3), x % UInt8) + end return n end @inline function __unsafe_string!(out, s::Union{String, SubString{String}}, offs::Integer) n = sizeof(s) - unsafe_copyto!(pointer(out, offs), pointer(s), n) + GC.@preserve s out unsafe_copyto!(pointer(out, offs), pointer(s), n) return n end @@ -200,7 +206,7 @@ function repeat(s::Union{String, SubString{String}}, r::Integer) ccall(:memset, Ptr{Cvoid}, (Ptr{UInt8}, Cint, Csize_t), out, b, r) else for i = 0:r-1 - unsafe_copyto!(pointer(out, i*n+1), pointer(s), n) + GC.@preserve s out unsafe_copyto!(pointer(out, i*n+1), pointer(s), n) end end return out diff --git a/base/strings/util.jl b/base/strings/util.jl index e0537ba3d6b0e..1d0acde9a545f 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -442,7 +442,7 @@ function replace(str::String, pat_repl::Pair; count::Integer=typemax(Int)) out = IOBuffer(sizehint=floor(Int, 1.2sizeof(str))) while j != 0 if i == a || i <= k - unsafe_write(out, pointer(str, i), UInt(j-i)) + GC.@preserve str unsafe_write(out, pointer(str, i), UInt(j-i)) _replace(out, repl, str, r, pattern) end if k < j diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index c2be8f53dfa24..ebaae7c2c447c 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -393,7 +393,7 @@ function (:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64} stop_n, stop_d = rat(stop) if start_d != 0 && stop_d != 0 && T(start_n/start_d) == start && T(stop_n/stop_d) == stop - den = lcm(start_d, step_d) # use same denominator for start and step + den = lcm_unchecked(start_d, step_d) # use same denominator for start and step m = maxintfloat(T, Int) if den != 0 && abs(start*den) <= m && abs(step*den) <= m && # will round succeed? rem(den, start_d) == 0 && rem(den, step_d) == 0 # check lcm overflow @@ -429,7 +429,7 @@ function _range(a::T, st::T, ::Nothing, len::Integer) where T<:Union{Float16,Flo step_n, step_d = rat(st) if start_d != 0 && step_d != 0 && T(start_n/start_d) == a && T(step_n/step_d) == st - den = lcm(start_d, step_d) + den = lcm_unchecked(start_d, step_d) m = maxintfloat(T, Int) if abs(den*a) <= m && abs(den*st) <= m && rem(den, start_d) == 0 && rem(den, step_d) == 0 @@ -513,7 +513,7 @@ function _convertSRL(::Type{StepRangeLen{T,R,S}}, r::AbstractRange{U}) where {T, step_n, step_d = rat(s) if start_d != 0 && step_d != 0 && U(start_n/start_d) == f && U(step_n/step_d) == s - den = lcm(start_d, step_d) + den = lcm_unchecked(start_d, step_d) m = maxintfloat(T, Int) if den != 0 && abs(f*den) <= m && abs(s*den) <= m && rem(den, start_d) == 0 && rem(den, step_d) == 0 @@ -582,7 +582,7 @@ function _range(start::T, ::Nothing, stop::T, len::Integer) where {T<:IEEEFloat} start_n, start_d = rat(start) stop_n, stop_d = rat(stop) if start_d != 0 && stop_d != 0 - den = lcm(start_d, stop_d) + den = lcm_unchecked(start_d, stop_d) m = maxintfloat(T, Int) if den != 0 && abs(den*start) <= m && abs(den*stop) <= m start_n = round(Int, den*start) @@ -691,6 +691,9 @@ function rat(x) return a, b end +# This version of lcm does not check for overflows +lcm_unchecked(a::T, b::T) where T<:Integer = a * div(b, gcd(a, b)) + narrow(::Type{T}) where {T<:AbstractFloat} = Float64 narrow(::Type{Float64}) = Float32 narrow(::Type{Float32}) = Float16 diff --git a/contrib/fixup-libgfortran.sh b/contrib/fixup-libgfortran.sh index fbe744bff65c7..d1f00bdf85950 100755 --- a/contrib/fixup-libgfortran.sh +++ b/contrib/fixup-libgfortran.sh @@ -3,6 +3,7 @@ # Run as: fixup-libgfortran.sh [--verbose] <$private_libdir> FC=${FC:-gfortran} +PATCHELF=${PATCHELF:-patchelf} # If we're invoked with "--verbose", create a `debug` function that prints stuff out if [ "$1" = "--verbose" ] || [ "$1" = "-v" ]; then @@ -126,7 +127,7 @@ change_linkage() echo " $old_link" install_name_tool -change "$old_link" "@rpath/$soname" "$lib_path" else # $UNAME is "Linux", we only have two options, see above - patchelf --set-rpath \$ORIGIN "$lib_path" + ${PATCHELF} --set-rpath \$ORIGIN "$lib_path" fi } diff --git a/deps/Versions.make b/deps/Versions.make index ee695e5cc28af..6cdf3814fa20a 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -40,4 +40,4 @@ P7ZIP_BB_REL = 1 # Specify the version of the Mozilla CA Certificate Store to obtain. # The versions of cacert.pem are identified by the date (YYYY-MM-DD) of their changes. # See https://curl.haxx.se/docs/caextract.html for more details. -MOZILLA_CACERT_VERSION := 2019-08-28 +MOZILLA_CACERT_VERSION := 2019-10-16 diff --git a/deps/checksums/Pkg-5de608c7b1837a24ed84eaaa14dde017986cb460.tar.gz/md5 b/deps/checksums/Pkg-5de608c7b1837a24ed84eaaa14dde017986cb460.tar.gz/md5 deleted file mode 100644 index 51de635e4d67b..0000000000000 --- a/deps/checksums/Pkg-5de608c7b1837a24ed84eaaa14dde017986cb460.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -fef000e6d59a8d47c58fd38d83c3ae51 diff --git a/deps/checksums/Pkg-5de608c7b1837a24ed84eaaa14dde017986cb460.tar.gz/sha512 b/deps/checksums/Pkg-5de608c7b1837a24ed84eaaa14dde017986cb460.tar.gz/sha512 deleted file mode 100644 index 41301b4512fc6..0000000000000 --- a/deps/checksums/Pkg-5de608c7b1837a24ed84eaaa14dde017986cb460.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -bfec28c1bfb906c44f91129074b44a795cb99bd971c60dd43abc74962e22ebef0e808039ded2345b7eb8ea42b4c8427b787a276642f0d27f96408e92c3f01bda diff --git a/deps/checksums/Pkg-f71e2c5a119b9c850f9b357fc8c56068f5b51cc0.tar.gz/md5 b/deps/checksums/Pkg-f71e2c5a119b9c850f9b357fc8c56068f5b51cc0.tar.gz/md5 new file mode 100644 index 0000000000000..8235b52698f7a --- /dev/null +++ b/deps/checksums/Pkg-f71e2c5a119b9c850f9b357fc8c56068f5b51cc0.tar.gz/md5 @@ -0,0 +1 @@ +054eb913fe9bcbe6080c2305980a6c6e diff --git a/deps/checksums/Pkg-f71e2c5a119b9c850f9b357fc8c56068f5b51cc0.tar.gz/sha512 b/deps/checksums/Pkg-f71e2c5a119b9c850f9b357fc8c56068f5b51cc0.tar.gz/sha512 new file mode 100644 index 0000000000000..62d0ba9df9841 --- /dev/null +++ b/deps/checksums/Pkg-f71e2c5a119b9c850f9b357fc8c56068f5b51cc0.tar.gz/sha512 @@ -0,0 +1 @@ +31c71b702b2831efe08911cab73b78aa2988524a5563720da902d1012e621c45e6bcad7310abc291e934be0d3f481d884af83e3cb4c63e284d8351938faf211f diff --git a/deps/checksums/cacert-2019-08-28.pem/md5 b/deps/checksums/cacert-2019-08-28.pem/md5 deleted file mode 100644 index c2b816d1ecd7f..0000000000000 --- a/deps/checksums/cacert-2019-08-28.pem/md5 +++ /dev/null @@ -1 +0,0 @@ -6c8779e5755d9dddf677bf7a52d035ce diff --git a/deps/checksums/cacert-2019-08-28.pem/sha512 b/deps/checksums/cacert-2019-08-28.pem/sha512 deleted file mode 100644 index 97b5e2963b7b4..0000000000000 --- a/deps/checksums/cacert-2019-08-28.pem/sha512 +++ /dev/null @@ -1 +0,0 @@ -527e23d1e83381583cc2efe4625b01a00baa990afc877bb617727e8bffab17a0dc4f36b60162bad375b576ff09bc27acc7e0f095a34150f23d61825b8a7fb81f diff --git a/deps/checksums/cacert-2019-10-16.pem/md5 b/deps/checksums/cacert-2019-10-16.pem/md5 new file mode 100644 index 0000000000000..5286d34293fa5 --- /dev/null +++ b/deps/checksums/cacert-2019-10-16.pem/md5 @@ -0,0 +1 @@ +5805059ab9e4646e4803ce1e007eb8ba diff --git a/deps/checksums/cacert-2019-10-16.pem/sha512 b/deps/checksums/cacert-2019-10-16.pem/sha512 new file mode 100644 index 0000000000000..e017d0fe86c31 --- /dev/null +++ b/deps/checksums/cacert-2019-10-16.pem/sha512 @@ -0,0 +1 @@ +49778472e46ce3b86b3930f4df5731ac86daf4d8602d418af1c89dc35df5f98c4557aa6c6eb280558c61139ead4b96cbb457a259f72640452f28a2fecd4ccb89 diff --git a/src/array.c b/src/array.c index a0627ff24ab8e..b268ad850a1ef 100644 --- a/src/array.c +++ b/src/array.c @@ -933,8 +933,8 @@ STATIC_INLINE void jl_array_shrink(jl_array_t *a, size_t dec) if (a->flags.how == 0) return; size_t elsz = a->elsize; - int newbytes = (a->maxsize - dec) * a->elsize; - int oldnbytes = (a->maxsize) * a->elsize; + size_t newbytes = (a->maxsize - dec) * a->elsize; + size_t oldnbytes = (a->maxsize) * a->elsize; int isbitsunion = jl_array_isbitsunion(a); if (isbitsunion) { newbytes += a->maxsize - dec; @@ -1107,7 +1107,7 @@ JL_DLLEXPORT void jl_array_sizehint(jl_array_t *a, size_t sz) { size_t n = jl_array_nrows(a); - int min = a->offset + a->length; + size_t min = a->offset + a->length; sz = (sz < min) ? min : sz; if (sz <= a->maxsize) { diff --git a/src/ast.scm b/src/ast.scm index b9d4ac24c19ca..7aab8d8256c5f 100644 --- a/src/ast.scm +++ b/src/ast.scm @@ -402,15 +402,17 @@ e) (define (vararg? x) (and (pair? x) (eq? (car x) '...))) -(define (varargexpr? x) (and - (pair? x) - (eq? (car x) '::) - (or - (eq? (caddr x) 'Vararg) - (and - (pair? (caddr x)) - (length> (caddr x) 1) - (eq? (cadr (caddr x)) 'Vararg))))) +(define (vararg-type-expr? x) + (or (eq? x 'Vararg) + (and (length> x 1) + (or (and (eq? (car x) 'curly) + (vararg-type-expr? (cadr x))) + (and (eq? (car x) 'where) + (vararg-type-expr? (cadr x))))))) +(define (varargexpr? x) + (and (pair? x) + (eq? (car x) '::) + (vararg-type-expr? (caddr x)))) (define (linenum? x) (and (pair? x) (eq? (car x) 'line))) (define (make-assignment l r) `(= ,l ,r)) diff --git a/src/ccall.cpp b/src/ccall.cpp index a19e3e092dd37..9bc661fd37c9b 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -4,7 +4,7 @@ // Map from symbol name (in a certain library) to its GV in sysimg and the // DL handle address in the current session. -typedef StringMap> SymMapGV; +typedef StringMap SymMapGV; static StringMap> libMapGV; #ifdef _OS_WINDOWS_ static SymMapGV symMapExe; @@ -43,65 +43,48 @@ lazyModule(Func &&func) // Find or create the GVs for the library and symbol lookup. // Return `runtime_lib` (whether the library name is a string) -// Optionally return the symbol address in the current session -// when `symaddr != nullptr`. // The `lib` and `sym` GV returned may not be in the current module. template static bool runtime_sym_gvs(const char *f_lib, const char *f_name, MT &&M, - GlobalVariable *&lib, GlobalVariable *&sym, - void **symaddr=nullptr) + GlobalVariable *&lib, GlobalVariable *&sym) { - void *libsym = NULL; bool runtime_lib = false; GlobalVariable *libptrgv; SymMapGV *symMap; #ifdef _OS_WINDOWS_ if ((intptr_t)f_lib == 1) { libptrgv = jlexe_var; - libsym = jl_exe_handle; symMap = &symMapExe; } else if ((intptr_t)f_lib == 2) { libptrgv = jldll_var; - libsym = jl_dl_handle; symMap = &symMapDl; } else #endif if (f_lib == NULL) { libptrgv = jlRTLD_DEFAULT_var; - libsym = jl_RTLD_DEFAULT_handle; symMap = &symMapDefault; } else { std::string name = "ccalllib_"; name += f_lib; runtime_lib = true; - auto iter = libMapGV.find(f_lib); - if (iter == libMapGV.end()) { + auto &libgv = libMapGV[f_lib]; + if (libgv.first == NULL) { libptrgv = new GlobalVariable(*M, T_pint8, false, GlobalVariable::ExternalLinkage, - NULL, name); - auto &libgv = libMapGV[f_lib]; - libgv = std::make_pair(global_proto(libptrgv), SymMapGV()); - symMap = &libgv.second; - libsym = jl_get_library(f_lib); - assert(libsym != NULL); - *jl_emit_and_add_to_shadow(libptrgv) = libsym; + Constant::getNullValue(T_pint8), name); + libgv.first = global_proto(libptrgv); } else { - libptrgv = iter->second.first; - symMap = &iter->second.second; + libptrgv = libgv.first; } + symMap = &libgv.second; } - if (libsym == NULL) { - libsym = *(void**)jl_get_globalvar(libptrgv); - } - assert(libsym != NULL); - GlobalVariable *llvmgv; - auto sym_iter = symMap->find(f_name); - if (sym_iter == symMap->end()) { + GlobalVariable *&llvmgv = (*symMap)[f_name]; + if (llvmgv == NULL) { // MCJIT forces this to have external linkage eventually, so we would clobber // the symbol of the actual function. std::string name = "ccall_"; @@ -109,19 +92,9 @@ static bool runtime_sym_gvs(const char *f_lib, const char *f_name, MT &&M, name += "_"; name += std::to_string(globalUnique++); llvmgv = new GlobalVariable(*M, T_pvoidfunc, false, - GlobalVariable::ExternalLinkage, NULL, name); + GlobalVariable::ExternalLinkage, + Constant::getNullValue(T_pvoidfunc), name); llvmgv = global_proto(llvmgv); - void *addr; - jl_dlsym(libsym, f_name, &addr, 0); - (*symMap)[f_name] = std::make_pair(llvmgv, addr); - if (symaddr) - *symaddr = addr; - *jl_emit_and_add_to_shadow(llvmgv) = addr; - } - else { - if (symaddr) - *symaddr = sym_iter->second.second; - llvmgv = sym_iter->second.first; } lib = libptrgv; @@ -218,7 +191,7 @@ static GlobalVariable *emit_plt_thunk( const AttributeList &attrs, CallingConv::ID cc, const char *f_lib, const char *f_name, GlobalVariable *libptrgv, GlobalVariable *llvmgv, - void *symaddr, bool runtime_lib) + bool runtime_lib) { PointerType *funcptype = PointerType::get(functype, 0); libptrgv = prepare_global_in(M, libptrgv); @@ -237,8 +210,7 @@ static GlobalVariable *emit_plt_thunk( auto gname = funcName.str(); GlobalVariable *got = new GlobalVariable(*M, T_pvoidfunc, false, GlobalVariable::ExternalLinkage, - nullptr, gname); - *jl_emit_and_add_to_shadow(got) = symaddr; + ConstantExpr::getBitCast(plt, T_pvoidfunc), gname); BasicBlock *b0 = BasicBlock::Create(jl_LLVMContext, "top", plt); IRBuilder<> irbuilder(b0); Value *ptr = runtime_sym_lookup(irbuilder, funcptype, f_lib, f_name, plt, libptrgv, @@ -274,6 +246,7 @@ static GlobalVariable *emit_plt_thunk( } } irbuilder.ClearInsertionPoint(); + got = global_proto(got); // exchange got for the permanent global before jl_finalize_module destroys it jl_finalize_module(M, true); @@ -297,21 +270,19 @@ static Value *emit_plt( assert(!functype->isVarArg()); GlobalVariable *libptrgv; GlobalVariable *llvmgv; - void *symaddr; auto LM = lazyModule([&] { Module *m = new Module(f_name, jl_LLVMContext); jl_setup_module(m); return m; }); - bool runtime_lib = runtime_sym_gvs(f_lib, f_name, LM, - libptrgv, llvmgv, &symaddr); + bool runtime_lib = runtime_sym_gvs(f_lib, f_name, LM, libptrgv, llvmgv); PointerType *funcptype = PointerType::get(functype, 0); auto &pltMap = allPltMap[attrs]; auto key = std::make_tuple(llvmgv, functype, cc); GlobalVariable *&shadowgot = pltMap[key]; if (!shadowgot) { - shadowgot = emit_plt_thunk(LM.get(), functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, symaddr, runtime_lib); + shadowgot = emit_plt_thunk(LM.get(), functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, runtime_lib); } else { // `runtime_sym_gvs` shouldn't have created anything in a new module diff --git a/src/codegen.cpp b/src/codegen.cpp index a0109f09b0c28..1d6e98dc8c94c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6869,8 +6869,10 @@ static std::unique_ptr emit_function( std::pair tbaa_make_child(const char *name, MDNode *parent=nullptr, bool isConstant=false) { MDBuilder mbuilder(jl_LLVMContext); - if (tbaa_root == nullptr) - tbaa_root = mbuilder.createTBAARoot("jtbaa"); + if (tbaa_root == nullptr) { + MDNode *jtbaa = mbuilder.createTBAARoot("jtbaa"); + tbaa_root = mbuilder.createTBAAScalarTypeNode("jtbaa", jtbaa); + } MDNode *scalar = mbuilder.createTBAAScalarTypeNode(name, parent ? parent : tbaa_root); MDNode *n = mbuilder.createTBAAStructTagNode(scalar, scalar, 0, isConstant); return std::make_pair(n, scalar); diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index cf339d8a4bdd3..2a8f2615d142e 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -474,13 +474,13 @@ void JuliaOJIT::addModule(std::unique_ptr M) { #ifndef JL_NDEBUG // validate the relocations for M - for (Module::iterator I = M->begin(), E = M->end(); I != E; ) { - Function *F = &*I; + for (Module::global_object_iterator I = M->global_object_begin(), E = M->global_object_end(); I != E; ) { + GlobalObject *F = &*I; ++I; if (F->isDeclaration()) { if (F->use_empty()) F->eraseFromParent(); - else if (!(isIntrinsicFunction(F) || + else if (!((isa(F) && isIntrinsicFunction(cast(F))) || findUnmangledSymbol(F->getName()) || SectionMemoryManager::getSymbolAddressInProcess( getMangledName(F->getName())))) { @@ -509,9 +509,10 @@ void JuliaOJIT::addModule(std::unique_ptr M) #endif // Force LLVM to emit the module so that we can register the symbols // in our lookup table. - auto Err = CompileLayer.emitAndFinalize(key); + Error Err = CompileLayer.emitAndFinalize(key); // Check for errors to prevent LLVM from crashing the program. - assert(!Err); + if (Err) + report_fatal_error(std::move(Err)); } void JuliaOJIT::removeModule(ModuleHandleT H) @@ -784,12 +785,15 @@ static void jl_merge_recursive(Module *m, Module *collector) // since the declarations may get destroyed by the jl_merge_module call. // this is also why we copy the Name string, rather than save a StringRef SmallVector to_finalize; - for (Module::iterator I = m->begin(), E = m->end(); I != E; ++I) { - Function *F = &*I; + for (Module::global_object_iterator I = m->global_object_begin(), E = m->global_object_end(); I != E; ++I) { + GlobalObject *F = &*I; if (!F->isDeclaration()) { module_for_fname.erase(F->getName()); } - else if (!isIntrinsicFunction(F)) { + else if (isa(F) && !isIntrinsicFunction(cast(F))) { + to_finalize.push_back(F->getName().str()); + } + else if (isa(F) && module_for_fname.count(F->getName())) { to_finalize.push_back(F->getName().str()); } } @@ -852,11 +856,13 @@ void jl_finalize_module(Module *m, bool shadow) { // record the function names that are part of this Module // so it can be added to the JIT when needed - for (Module::iterator I = m->begin(), E = m->end(); I != E; ++I) { - Function *F = &*I; + for (Module::global_object_iterator I = m->global_object_begin(), E = m->global_object_end(); I != E; ++I) { + GlobalObject *F = &*I; if (!F->isDeclaration()) { - bool known = incomplete_fname.erase(F->getName()); - (void)known; // TODO: assert(known); // llvmcall gets this wrong + if (isa(F)) { + bool known = incomplete_fname.erase(F->getName()); + (void)known; // TODO: assert(known); // llvmcall gets this wrong + } module_for_fname[F->getName()] = m; } } diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 8e14e76df7bc8..3934291f71798 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -1111,8 +1111,7 @@ (cond ((eventually-call? (cadar binds)) ;; f() = c - (let ((asgn (butlast (expand-forms (car binds)))) - (name (assigned-name (cadar binds)))) + (let ((name (assigned-name (cadar binds)))) (if (not (symbol? name)) (error "invalid let syntax")) (loop (cdr binds) @@ -1121,7 +1120,7 @@ ,(if (expr-contains-eq name (caddar binds)) `(local ,name) ;; might need a Box for recursive functions `(local-def ,name)) - ,asgn + ,(car binds) ,blk))))) ((or (symbol? (cadar binds)) (decl? (cadar binds))) diff --git a/src/subtype.c b/src/subtype.c index 5b963dfb6f4e8..91f586bd1e52b 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -1333,10 +1333,37 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param) return x == y || jl_egal(x, y); } +static int is_indefinite_length_tuple_type(jl_value_t *x) +{ + x = jl_unwrap_unionall(x); + if (!jl_is_tuple_type(x)) + return 0; + size_t n = jl_nparams(x); + return n > 0 && jl_vararg_kind(jl_tparam(x, n-1)) == JL_VARARG_UNBOUND; +} + +static int is_definite_length_tuple_type(jl_value_t *x) +{ + if (jl_is_typevar(x)) + x = ((jl_tvar_t*)x)->ub; + x = jl_unwrap_unionall(x); + if (!jl_is_tuple_type(x)) + return 0; + size_t n = jl_nparams(x); + if (n == 0) + return 1; + jl_vararg_kind_t k = jl_vararg_kind(jl_tparam(x, n-1)); + return k == JL_VARARG_NONE || k == JL_VARARG_INT; +} + static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) { if (obviously_egal(x, y)) return 1; + if ((is_indefinite_length_tuple_type(x) && is_definite_length_tuple_type(y)) || + (is_definite_length_tuple_type(x) && is_indefinite_length_tuple_type(y))) + return 0; + jl_unionstate_t oldLunions = e->Lunions; memset(e->Lunions.stack, 0, sizeof(e->Lunions.stack)); int sub; diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 926c9be90aa9e..417959382c111 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,2 +1,2 @@ PKG_BRANCH = master -PKG_SHA1 = 5de608c7b1837a24ed84eaaa14dde017986cb460 +PKG_SHA1 = f71e2c5a119b9c850f9b357fc8c56068f5b51cc0 diff --git a/test/arrayops.jl b/test/arrayops.jl index c1eb1156bad61..4f4f9c53b865b 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -2657,3 +2657,14 @@ end C = hcat(A, B) @test typeof(C) == Array{Array{Float64,2},2} end + +# issue #33974 +let n = 12000000, k = 257000000 + # tests skipped since they use a lot of memory + @test_skip filter(x -> x[2] < 1.0, collect(enumerate(vcat(fill(0.5, n), fill(NaN, k)))))[end] == (n, 0.5) + @test_skip let v = collect(enumerate(vcat(fill(0.5, n), fill(NaN, k)))) + resize!(v, n) + sizehint!(v, n) + v[end] == (n, 0.5) + end +end diff --git a/test/ccall.jl b/test/ccall.jl index 6aa61a41590f5..08335390de221 100644 --- a/test/ccall.jl +++ b/test/ccall.jl @@ -1535,3 +1535,14 @@ let @test isa(ptr, Ptr{Cvoid}) @test arr[1] == '0' end + +# issue #34061 +o_file = tempname() +output = read(Cmd(`$(Base.julia_cmd()) --output-o=$o_file -e 'Base.reinit_stdio(); + f() = ccall((:dne, :does_not_exist), Cvoid, ()); + f()'`; ignorestatus=true), String) +@test occursin(output, """ +ERROR: could not load library "does_not_exist" +does_not_exist.so: cannot open shared object file: No such file or directory +""") +@test !isfile(o_file) diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index da25fac0da10f..755cab076a5aa 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -391,3 +391,11 @@ end # Warm up f_dict_hash_alloc(); g_dict_hash_alloc(); @test (@allocated f_dict_hash_alloc()) == (@allocated g_dict_hash_alloc()) + +# issue 33590 +function f33590(b, x) + y = b ? nothing : (x[1] + 1,) + return something(ifelse(b, x, y)) +end +@test f33590(true, (3,)) == (3,) +@test f33590(false, (3,)) == (4,) diff --git a/test/intfuncs.jl b/test/intfuncs.jl index 9065e85206511..1214172c20b73 100644 --- a/test/intfuncs.jl +++ b/test/intfuncs.jl @@ -35,6 +35,7 @@ using Random @test lcm(-typemax(T), T(1)) === typemax(T) @test_throws OverflowError lcm(typemin(T), T(1)) @test_throws OverflowError lcm(typemin(T), typemin(T)) + @test_throws OverflowError lcm(typemax(T), T(2)) end end @testset "gcd/lcm for arrays" begin diff --git a/test/llvmpasses/late-lower-gc.ll b/test/llvmpasses/late-lower-gc.ll index e6987bd635d38..1d38522b5da9f 100644 --- a/test/llvmpasses/late-lower-gc.ll +++ b/test/llvmpasses/late-lower-gc.ll @@ -65,11 +65,11 @@ top: %v = call noalias %jl_value_t addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, i64 8, %jl_value_t addrspace(10)* @tag) ; CHECK-NEXT: %v64 = bitcast %jl_value_t addrspace(10)* %v to i64 addrspace(10)* %v64 = bitcast %jl_value_t addrspace(10)* %v to i64 addrspace(10)* -; CHECK-NEXT: %loadedval = load i64, i64 addrspace(10)* %v64, align 8, !range !4 +; CHECK-NEXT: %loadedval = load i64, i64 addrspace(10)* %v64, align 8, !range !5 %loadedval = load i64, i64 addrspace(10)* %v64, align 8, !range !0, !invariant.load !1 -; CHECK-NEXT: store i64 %loadedval, i64 addrspace(10)* %v64, align 8, !noalias !5 +; CHECK-NEXT: store i64 %loadedval, i64 addrspace(10)* %v64, align 8, !noalias !6 store i64 %loadedval, i64 addrspace(10)* %v64, align 8, !noalias !2 -; CHECK-NEXT: %lv2 = load i64, i64 addrspace(10)* %v64, align 8, !tbaa !6, !range !4 +; CHECK-NEXT: %lv2 = load i64, i64 addrspace(10)* %v64, align 8, !tbaa !7, !range !5 %lv2 = load i64, i64 addrspace(10)* %v64, align 8, !range !0, !tbaa !4 ; CHECK-NEXT: ret void ret void @@ -85,9 +85,10 @@ top: ; CHECK: !0 = !{!1, !1, i64 0} ; CHECK-NEXT: !1 = !{!"jtbaa_tag", !2, i64 0} ; CHECK-NEXT: !2 = !{!"jtbaa_data", !3, i64 0} -; CHECK-NEXT: !3 = !{!"jtbaa"} -; CHECK-NEXT: !4 = !{i64 0, i64 23} -; CHECK-NEXT: !5 = distinct !{!5} -; CHECK-NEXT: !6 = !{!7, !7, i64 0} -; CHECK-NEXT: !7 = !{!"jtbaa_const", !8} -; CHECK-NEXT: !8 = !{!"jtbaa"} +; CHECK-NEXT: !3 = !{!"jtbaa", !4, i64 0} +; CHECK-NEXT: !4 = !{!"jtbaa"} +; CHECK-NEXT: !5 = !{i64 0, i64 23} +; CHECK-NEXT: !6 = distinct !{!6} +; CHECK-NEXT: !7 = !{!8, !8, i64 0} +; CHECK-NEXT: !8 = !{!"jtbaa_const", !9} +; CHECK-NEXT: !9 = !{!"jtbaa"} diff --git a/test/offsetarray.jl b/test/offsetarray.jl index dad4cad1da757..8a14384c58f71 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -495,6 +495,19 @@ A = OffsetArray(rand(4,4), (-3,5)) @test vec(A) == reshape(A, :) == reshape(A, 16) == reshape(A, Val(1)) == A[:] == vec(A.parent) A = OffsetArray(view(rand(4,4), 1:4, 4:-1:1), (-3,5)) @test vec(A) == reshape(A, :) == reshape(A, 16) == reshape(A, Val(1)) == A[:] == vec(A.parent) +# issue #33614 +A = OffsetArray(-1:0, (-2,)) +@test reshape(A, :) === A +Arsc = reshape(A, :, 1) +Arss = reshape(A, 2, 1) +@test Arsc[1,1] == Arss[1,1] == -1 +@test Arsc[2,1] == Arss[2,1] == 0 +@test_throws BoundsError Arsc[0,1] +@test_throws BoundsError Arss[0,1] +A = OffsetArray([-1,0], (-2,)) +Arsc = reshape(A, :, 1) +Arsc[1,1] = 5 +@test first(A) == 5 # broadcast a = [1] diff --git a/test/spawn.jl b/test/spawn.jl index d62179724097f..0122cb9d2b0a7 100644 --- a/test/spawn.jl +++ b/test/spawn.jl @@ -20,7 +20,7 @@ sleepcmd = `sleep` lscmd = `ls` havebb = false if Sys.iswindows() - busybox = download("https://frippery.org/files/busybox/busybox.exe", joinpath(tempdir(), "busybox.exe")) + busybox = download("https://cache.julialang.org/https://frippery.org/files/busybox/busybox.exe", joinpath(tempdir(), "busybox.exe")) havebb = try # use busybox-w32 on windows, if available success(`$busybox`) true diff --git a/test/strings/basic.jl b/test/strings/basic.jl index aa928c88aa961..40c4002834d2b 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -637,6 +637,17 @@ end @test "a" * 'b' * 'c' == "abc" end +# this tests a possible issue in subtyping with long argument lists to `string(...)` +getString(dic, key) = haskey(dic,key) ? "$(dic[key])" : "" +function getData(dic) + val = getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") * + "," * getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") * + "," * getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") * + "," * getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") * + "," * getString(dic,"") * "," * getString(dic,"") * "," * getString(dic,"") +end +@test getData(Dict()) == ",,,,,,,,,,,,,,,,,," + @testset "unrecognized escapes in string/char literals" begin @test_throws Meta.ParseError Meta.parse("\"\\.\"") @test_throws Meta.ParseError Meta.parse("\'\\.\'") diff --git a/test/subtype.jl b/test/subtype.jl index cd4b2040fcc5a..9d591c8b0b1e0 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1682,3 +1682,6 @@ c32703(::Type{<:Str{C}}, str::Str{C}) where {C<:CSE} = str Tuple{Type{Tuple{Vararg{V, N} where N}}, Tuple{Vararg{V, N} where N}} where V) @test issub(Tuple{Type{Any}, NTuple{4,Union{Int,Nothing}}}, Tuple{Type{V}, Tuple{Vararg{V, N} where N}} where V) + +@test !issub(Tuple{Type{T}, T} where T<:Tuple{String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}}, + Tuple{Type{Tuple{Vararg{V, N} where N}}, Tuple{Vararg{V, N} where N}} where V) diff --git a/test/syntax.jl b/test/syntax.jl index bfe9f86a62a50..bdf5e607f46dc 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -1938,3 +1938,12 @@ end # issue #33227 @test Meta.isexpr(Meta.lower(Main, :((@label a; @goto a))), :thunk) + +# issue #33841 +let a(; b) = b + @test a(b=3) == 3 +end + +# issue #33987 +f33987(args::(Vararg{Any, N} where N); kwargs...) = args +@test f33987(1,2,3) === (1,2,3)