diff --git a/.travis.yml b/.travis.yml index b227c5832dc5f..6bbca3bc3a52d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ matrix: - gfortran-5 - os: osx env: ARCH="x86_64" - osx_image: xcode8 + osx_image: xcode8.3 cache: ccache branches: only: diff --git a/base/abstractset.jl b/base/abstractset.jl index 100383a126a1d..03038ff6364da 100644 --- a/base/abstractset.jl +++ b/base/abstractset.jl @@ -67,9 +67,11 @@ function union!(s::AbstractSet, sets...) end max_values(::Type) = typemax(Int) -max_values(T::Type{<:Union{Nothing,BitIntegerSmall}}) = 1 << (8*sizeof(T)) -max_values(T::Union) = max(max_values(T.a), max_values(T.b)) +max_values(T::Union{map(X -> Type{X}, BitIntegerSmall_types)...}) = 1 << (8*sizeof(T)) +# saturated addition to prevent overflow with typemax(Int) +max_values(T::Union) = max(max_values(T.a), max_values(T.b), max_values(T.a) + max_values(T.b)) max_values(::Type{Bool}) = 2 +max_values(::Type{Nothing}) = 1 function union!(s::AbstractSet{T}, itr) where T haslength(itr) && sizehint!(s, length(s) + length(itr)) diff --git a/base/arrayshow.jl b/base/arrayshow.jl index e1051502da706..0b000db83c537 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -434,10 +434,11 @@ function show_vector(io::IO, v, opn='[', cls=']') io = IOContext(io, :typeinfo => eltype(v), :compact => get(io, :compact, true)) limited = get(io, :limit, false) if limited && length(v) > 20 - inds = axes1(v) - show_delim_array(io, v, opn, ",", "", false, inds[1], inds[1]+9) + axs1 = axes1(v) + f, l = first(axs1), last(axs1) + show_delim_array(io, v, opn, ",", "", false, f, f+9) print(io, " … ") - show_delim_array(io, v, "", ",", cls, false, inds[end-9], inds[end]) + show_delim_array(io, v, "", ",", cls, false, l-9, l) else show_delim_array(io, v, opn, ",", cls, false) end diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index ce04b81bac1eb..12cd0cd582f8c 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -130,7 +130,7 @@ function simple_walk(compact::IncrementalCompact, @nospecialize(defssa#=::AnySSA return defssa end if isa(def.val, SSAValue) - if isa(defssa, OldSSAValue) && !already_inserted(compact, defssa) + if is_old(compact, defssa) defssa = OldSSAValue(def.val.id) else defssa = def.val @@ -191,7 +191,7 @@ function walk_to_defs(compact::IncrementalCompact, @nospecialize(defssa), @nospe collect(Iterators.filter(1:length(def.edges)) do n isassigned(def.values, n) || return false val = def.values[n] - if isa(defssa, OldSSAValue) && isa(val, SSAValue) + if is_old(compact, defssa) && isa(val, SSAValue) val = OldSSAValue(val.id) end edge_typ = widenconst(compact_exprtype(compact, val)) @@ -201,7 +201,7 @@ function walk_to_defs(compact::IncrementalCompact, @nospecialize(defssa), @nospe for n in possible_predecessors pred = def.edges[n] val = def.values[n] - if isa(defssa, OldSSAValue) && isa(val, SSAValue) + if is_old(compact, defssa) && isa(val, SSAValue) val = OldSSAValue(val.id) end if isa(val, AnySSAValue) @@ -281,7 +281,7 @@ function lift_leaves(compact::IncrementalCompact, @nospecialize(stmt), end if is_tuple_call(compact.ir, def) && isa(field, Int) && 1 <= field < length(def.args) lifted = def.args[1+field] - if isa(leaf, OldSSAValue) && isa(lifted, SSAValue) + if is_old(compact, leaf) && isa(lifted, SSAValue) lifted = OldSSAValue(lifted.id) end if isa(lifted, GlobalRef) || isa(lifted, Expr) @@ -320,7 +320,7 @@ function lift_leaves(compact::IncrementalCompact, @nospecialize(stmt), compact[leaf] = def end lifted = def.args[1+field] - if isa(leaf, OldSSAValue) && isa(lifted, SSAValue) + if is_old(compact, leaf) && isa(lifted, SSAValue) lifted = OldSSAValue(lifted.id) end if isa(lifted, GlobalRef) || isa(lifted, Expr) @@ -339,7 +339,7 @@ function lift_leaves(compact::IncrementalCompact, @nospecialize(stmt), # N.B.: This can be a bit dangerous because it can lead to # infinite loops if we accidentally insert a node just ahead # of where we are - if isa(leaf, OldSSAValue) && (isa(field, Int) || isa(field, Symbol)) + if is_old(compact, leaf) && (isa(field, Int) || isa(field, Symbol)) (isa(typ, DataType) && (!typ.abstract)) || return nothing @assert !typ.mutable # If there's the potential for an undefref error on access, we cannot insert a getfield @@ -425,6 +425,12 @@ struct LiftedPhi need_argupdate::Bool end +function is_old(compact, @nospecialize(old_node_ssa)) + isa(old_node_ssa, OldSSAValue) && + !is_pending(compact, old_node_ssa) && + !already_inserted(compact, old_node_ssa) +end + function perform_lifting!(compact::IncrementalCompact, visited_phinodes::Vector{Any}, @nospecialize(cache_key), lifting_cache::IdDict{Pair{AnySSAValue, Any}, AnySSAValue}, @@ -455,7 +461,7 @@ function perform_lifting!(compact::IncrementalCompact, isassigned(old_node.values, i) || continue val = old_node.values[i] orig_val = val - if isa(old_node_ssa, OldSSAValue) && !is_pending(compact, old_node_ssa) && !already_inserted(compact, old_node_ssa) && isa(val, SSAValue) + if is_old(compact, old_node_ssa) && isa(val, SSAValue) val = OldSSAValue(val.id) end if isa(val, Union{NewSSAValue, SSAValue, OldSSAValue}) @@ -688,10 +694,14 @@ function getfield_elim_pass!(ir::IRCode, domtree::DomTree) compact[idx] = val === nothing ? nothing : val.x end - # Copy the use count, `finish` may modify it and for our predicate - # below we need it consistent with the state of the IR here. + + non_dce_finish!(compact) + # Copy the use count, `simple_dce!` may modify it and for our predicate + # below we need it consistent with the state of the IR here (after tracking + # phi node arguments, but before dce). used_ssas = copy(compact.used_ssas) - ir = finish(compact) + simple_dce!(compact) + ir = complete(compact) # Now go through any mutable structs and see which ones we can eliminate for (idx, (intermediaries, defuse)) in defuses intermediaries = collect(intermediaries) diff --git a/base/deepcopy.jl b/base/deepcopy.jl index 7ed68bbf2b6ac..5bf1311a13603 100644 --- a/base/deepcopy.jl +++ b/base/deepcopy.jl @@ -27,7 +27,7 @@ updated as appropriate before returning. """ deepcopy(x) = deepcopy_internal(x, IdDict())::typeof(x) -deepcopy_internal(x::Union{Symbol,Core.MethodInstance,Method,GlobalRef,DataType,Union,Task}, +deepcopy_internal(x::Union{Symbol,Core.MethodInstance,Method,GlobalRef,DataType,Union,UnionAll,Task}, stackdict::IdDict) = x deepcopy_internal(x::Tuple, stackdict::IdDict) = ntuple(i->deepcopy_internal(x[i], stackdict), length(x)) diff --git a/base/iterators.jl b/base/iterators.jl index 449e8dbb0663d..118cb9b61c5de 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -1094,10 +1094,9 @@ end @inline peek(s::Stateful, sentinel=nothing) = s.nextvalstate !== nothing ? s.nextvalstate[1] : sentinel @inline iterate(s::Stateful, state=nothing) = s.nextvalstate === nothing ? nothing : (popfirst!(s), nothing) -IteratorSize(::Type{Stateful{VS,T}} where VS) where {T} = - isa(IteratorSize(T), SizeUnknown) ? SizeUnknown() : HasLength() +IteratorSize(::Type{Stateful{T,VS}}) where {T,VS} = IteratorSize(T) isa HasShape ? HasLength() : IteratorSize(T) eltype(::Type{Stateful{T, VS}} where VS) where {T} = eltype(T) -IteratorEltype(::Type{Stateful{VS,T}} where VS) where {T} = IteratorEltype(T) +IteratorEltype(::Type{Stateful{T,VS}}) where {T,VS} = IteratorEltype(T) length(s::Stateful) = length(s.itr) - s.taken end diff --git a/base/parse.jl b/base/parse.jl index 202390278e9f5..9cde8054435bd 100644 --- a/base/parse.jl +++ b/base/parse.jl @@ -309,7 +309,7 @@ function tryparse_internal(::Type{Complex{T}}, s::Union{String,SubString{String} end if i₊ == 0 # purely real or imaginary value - if iᵢ > 0 # purely imaginary + if iᵢ > i && !(iᵢ == i+1 && s[i] in ('+','-')) # purely imaginary (not "±inf") x = tryparse_internal(T, s, i, iᵢ-1, raise) x === nothing && return nothing return Complex{T}(zero(x),x) diff --git a/base/range.jl b/base/range.jl index af28228cd74ac..517d0456db5e8 100644 --- a/base/range.jl +++ b/base/range.jl @@ -608,8 +608,8 @@ function getindex(v::AbstractRange{T}, i::Integer) where T @_inline_meta ret = convert(T, first(v) + (i - 1)*step_hp(v)) ok = ifelse(step(v) > zero(step(v)), - (ret <= v.stop) & (ret >= v.start), - (ret <= v.start) & (ret >= v.stop)) + (ret <= last(v)) & (ret >= first(v)), + (ret <= first(v)) & (ret >= last(v))) @boundscheck ((i > 0) & ok) || throw_boundserror(v, i) ret end diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 2ea21ec981b56..d910b13d3551c 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -33,8 +33,8 @@ struct ReinterpretArray{T,N,S,A<:AbstractArray{S, N}} <: AbstractArray{T, N} isbitstype(T) || throwbits(S, T, T) isbitstype(S) || throwbits(S, T, S) (N != 0 || sizeof(T) == sizeof(S)) || throwsize0(S, T) - ax1 = axes(a)[1] if N != 0 && sizeof(S) != sizeof(T) + ax1 = axes(a)[1] dim = length(ax1) rem(dim*sizeof(S),sizeof(T)) == 0 || thrownonint(S, T, dim) first(ax1) == 1 || throwaxes1(S, T, ax1) @@ -68,12 +68,14 @@ IndexStyle(a::ReinterpretArray) = IndexStyle(a.parent) parent(a::ReinterpretArray) = a.parent dataids(a::ReinterpretArray) = dataids(a.parent) +unaliascopy(a::ReinterpretArray{T}) where {T} = reinterpret(T, unaliascopy(a.parent)) function size(a::ReinterpretArray{T,N,S} where {N}) where {T,S} psize = size(a.parent) size1 = div(psize[1]*sizeof(S), sizeof(T)) tuple(size1, tail(psize)...) end +size(a::ReinterpretArray{T,0}) where {T} = () function axes(a::ReinterpretArray{T,N,S} where {N}) where {T,S} paxs = axes(a.parent) @@ -81,6 +83,7 @@ function axes(a::ReinterpretArray{T,N,S} where {N}) where {T,S} size1 = div(l*sizeof(S), sizeof(T)) tuple(oftype(paxs[1], f:f+size1-1), tail(paxs)...) end +axes(a::ReinterpretArray{T,0}) where {T} = () elsize(::Type{<:ReinterpretArray{T}}) where {T} = sizeof(T) unsafe_convert(::Type{Ptr{T}}, a::ReinterpretArray{T,N,S} where N) where {T,S} = Ptr{T}(unsafe_convert(Ptr{S},a.parent)) diff --git a/base/strings/util.jl b/base/strings/util.jl index ad27f9c7f84e6..ff9beab76b9c5 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -96,6 +96,9 @@ julia> chop(a, head = 5, tail = 5) ``` """ function chop(s::AbstractString; head::Integer = 0, tail::Integer = 1) + if isempty(s) + return SubString(s) + end SubString(s, nextind(s, firstindex(s), head), prevind(s, lastindex(s), tail)) end diff --git a/contrib/mac/app/julia.icns b/contrib/mac/app/julia.icns index 691f1be5d1cfa..16358e19db453 100644 Binary files a/contrib/mac/app/julia.icns and b/contrib/mac/app/julia.icns differ diff --git a/deps/Versions.make b/deps/Versions.make index ea8c5d118afd4..ae86096789c9e 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -7,7 +7,7 @@ SUITESPARSE_VER = 4.4.5 UNWIND_VER = 1.1-julia2 OSXUNWIND_VER = 0.0.5 GMP_VER = 6.1.2 -MPFR_VER = 4.0.1 +MPFR_VER = 4.0.2 PATCHELF_VER = 0.9 MBEDTLS_VER = 2.6.0 CURL_VER = 7.56.0 @@ -15,4 +15,4 @@ CURL_VER = 7.56.0 # 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 := 2018-06-20 +MOZILLA_CACERT_VERSION := 2019-01-23 diff --git a/deps/checksums/Pkg-1609a05aee5d5960670738d8d834d91235bd6b1e.tar.gz/md5 b/deps/checksums/Pkg-1609a05aee5d5960670738d8d834d91235bd6b1e.tar.gz/md5 new file mode 100644 index 0000000000000..8f26008493d67 --- /dev/null +++ b/deps/checksums/Pkg-1609a05aee5d5960670738d8d834d91235bd6b1e.tar.gz/md5 @@ -0,0 +1 @@ +4e0bcbf65c67c86b1604e103db173d77 diff --git a/deps/checksums/Pkg-1609a05aee5d5960670738d8d834d91235bd6b1e.tar.gz/sha512 b/deps/checksums/Pkg-1609a05aee5d5960670738d8d834d91235bd6b1e.tar.gz/sha512 new file mode 100644 index 0000000000000..573874903aac6 --- /dev/null +++ b/deps/checksums/Pkg-1609a05aee5d5960670738d8d834d91235bd6b1e.tar.gz/sha512 @@ -0,0 +1 @@ +95022a2aee8bca4b8e1ce65b5e5840209cd7adb7d048a647c9501e15e0ebd37fb4e4a95e707a5ec001893789ae841e3300a615f8e21a711694fc288777eed726 diff --git a/deps/checksums/Pkg-93b6d6de857dc88e665d2c64397852ab9701ba24.tar.gz/md5 b/deps/checksums/Pkg-93b6d6de857dc88e665d2c64397852ab9701ba24.tar.gz/md5 deleted file mode 100644 index 15f8d03acf4f8..0000000000000 --- a/deps/checksums/Pkg-93b6d6de857dc88e665d2c64397852ab9701ba24.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -498ed1792ccd8e3a895edf290d8066ca diff --git a/deps/checksums/Pkg-93b6d6de857dc88e665d2c64397852ab9701ba24.tar.gz/sha512 b/deps/checksums/Pkg-93b6d6de857dc88e665d2c64397852ab9701ba24.tar.gz/sha512 deleted file mode 100644 index da1d5635eedc0..0000000000000 --- a/deps/checksums/Pkg-93b6d6de857dc88e665d2c64397852ab9701ba24.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -83143d69e27da5fa58e5fa1ceab41aff7af242eea5399d4512c381d12fd90c7a3106db2a84af1f9a33c5bb917e7f05208310f34fd3b182595b581dc8070e3491 diff --git a/deps/checksums/cacert-2019-01-23.pem/md5 b/deps/checksums/cacert-2019-01-23.pem/md5 new file mode 100644 index 0000000000000..24c61558beb49 --- /dev/null +++ b/deps/checksums/cacert-2019-01-23.pem/md5 @@ -0,0 +1 @@ +fccbe6cec7a76e3351ad32e305184787 diff --git a/deps/checksums/cacert-2019-01-23.pem/sha512 b/deps/checksums/cacert-2019-01-23.pem/sha512 new file mode 100644 index 0000000000000..94305a88a3b68 --- /dev/null +++ b/deps/checksums/cacert-2019-01-23.pem/sha512 @@ -0,0 +1 @@ +01faebab60b49a30736e0c88b713999f48c99b425889f7df9bbb80eb91367a6f26f20befdf8ac72b8d77659b143b7b37f91ad7dac5fde37c1d621fc663003687 diff --git a/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/md5 b/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/md5 new file mode 100644 index 0000000000000..7091746b1815f --- /dev/null +++ b/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/md5 @@ -0,0 +1 @@ +bcf01c3fa49a1684edc2d637ad7e03d6 diff --git a/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/sha512 b/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/sha512 new file mode 100644 index 0000000000000..2d6d2980fa7f2 --- /dev/null +++ b/deps/checksums/libssh2-02ecf17a6d5f9837699e8fb3aad0c804caa67eeb.tar.gz/sha512 @@ -0,0 +1 @@ +ae4c798ae5c13ad1574646896665ccd1f7d91e64573a23662ce7016b00109c1c351013856c25bf12284d9c3996ca3b828506825e50fcb059969adc02a96c06f8 diff --git a/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/md5 b/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/md5 deleted file mode 100644 index a2fc72b9885cc..0000000000000 --- a/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -d251ef0efecff323b6f570cc737d3411 diff --git a/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/sha512 b/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/sha512 deleted file mode 100644 index 1db563c8be7bb..0000000000000 --- a/deps/checksums/libssh2-30e9c1347e3b8baa2951db612f05e6d87fc8e2f2.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -ae7535cf8f70e7c837e80365cd9ee7c4040d45e952871a3e5c8f1b71bd8eb2d96babb07fa4c5d66a83bb45960728ef8dbba30ab9a6387a68cf815a84cdae8795 diff --git a/deps/checksums/mpfr-4.0.1.tar.bz2/md5 b/deps/checksums/mpfr-4.0.1.tar.bz2/md5 deleted file mode 100644 index 0033858e5788e..0000000000000 --- a/deps/checksums/mpfr-4.0.1.tar.bz2/md5 +++ /dev/null @@ -1 +0,0 @@ -8c21d8ac7460493b2b9f3ef3cc610454 diff --git a/deps/checksums/mpfr-4.0.1.tar.bz2/sha512 b/deps/checksums/mpfr-4.0.1.tar.bz2/sha512 deleted file mode 100644 index 42c78a8b089dd..0000000000000 --- a/deps/checksums/mpfr-4.0.1.tar.bz2/sha512 +++ /dev/null @@ -1 +0,0 @@ -c1674fc0a5edcde188bdf7d6d14063cfb4f1259b9eaf39d0081f7176e9921ca0af1b12b7aba1a9560d9f2d5f37329d22bc7b82f13421d91d83114b439bc60dcc diff --git a/deps/checksums/mpfr-4.0.2.tar.bz2/md5 b/deps/checksums/mpfr-4.0.2.tar.bz2/md5 new file mode 100644 index 0000000000000..8639e86c33058 --- /dev/null +++ b/deps/checksums/mpfr-4.0.2.tar.bz2/md5 @@ -0,0 +1 @@ +6d8a8bb46fe09ff44e21cdbf84f5cdac diff --git a/deps/checksums/mpfr-4.0.2.tar.bz2/sha512 b/deps/checksums/mpfr-4.0.2.tar.bz2/sha512 new file mode 100644 index 0000000000000..d073360a775c8 --- /dev/null +++ b/deps/checksums/mpfr-4.0.2.tar.bz2/sha512 @@ -0,0 +1 @@ +18bb3a87123d02b7537bc298d41bdbb33e58b8c196cc4040578e3b470e86c6c89e1bd8ab8b3919d106fe5b86922ef8999dc1aba7c521ee90a69f690be288a30d diff --git a/deps/gmp.mk b/deps/gmp.mk index 347d20df65ee3..698d2d07c6a48 100644 --- a/deps/gmp.mk +++ b/deps/gmp.mk @@ -21,7 +21,13 @@ $(SRCCACHE)/gmp-$(GMP_VER)/build-patched: $(SRCCACHE)/gmp-$(GMP_VER)/source-extr cd $(dir $@) && patch < $(SRCDIR)/patches/gmp-exception.patch echo 1 > $@ -$(BUILDDIR)/gmp-$(GMP_VER)/build-configured: $(SRCCACHE)/gmp-$(GMP_VER)/source-extracted $(SRCCACHE)/gmp-$(GMP_VER)/build-patched +$(SRCCACHE)/gmp-$(GMP_VER)/gmp-config-ldflags.patch-applied: | $(SRCCACHE)/gmp-$(GMP_VER)/build-patched + cd $(dir $@) && patch -p1 < $(SRCDIR)/patches/gmp-config-ldflags.patch + echo 1 > $@ + +$(BUILDDIR)/gmp-$(GMP_VER)/build-configured: $(SRCCACHE)/gmp-$(GMP_VER)/gmp-config-ldflags.patch-applied + +$(BUILDDIR)/gmp-$(GMP_VER)/build-configured: $(SRCCACHE)/gmp-$(GMP_VER)/source-extracted mkdir -p $(dir $@) cd $(dir $@) && \ $(dir $<)/configure $(CONFIGURE_COMMON) F77= --enable-shared --disable-static $(GMP_CONFIGURE_OPTS) diff --git a/deps/libssh2.version b/deps/libssh2.version index dadad22483c2a..fe1ecb3080028 100644 --- a/deps/libssh2.version +++ b/deps/libssh2.version @@ -1,2 +1,2 @@ -LIBSSH2_BRANCH=libssh2-1.8.0 -LIBSSH2_SHA1=30e9c1347e3b8baa2951db612f05e6d87fc8e2f2 +LIBSSH2_BRANCH=libssh2-1.8.2 +LIBSSH2_SHA1=02ecf17a6d5f9837699e8fb3aad0c804caa67eeb diff --git a/deps/llvm.mk b/deps/llvm.mk index 5af5f6363d5c6..d09579b21e27e 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -65,7 +65,7 @@ LLVM_CXXFLAGS += $(CXXFLAGS) LLVM_CPPFLAGS += $(CPPFLAGS) LLVM_LDFLAGS += $(LDFLAGS) LLVM_CMAKE += -DLLVM_TARGETS_TO_BUILD:STRING="$(LLVM_TARGETS)" -DCMAKE_BUILD_TYPE="$(LLVM_CMAKE_BUILDTYPE)" -LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBXML2=OFF +LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_HOST_TRIPLE="$(or $(XC_HOST),$(BUILD_MACHINE))" ifeq ($(USE_POLLY_ACC),1) LLVM_CMAKE += -DPOLLY_ENABLE_GPGPU_CODEGEN=ON endif diff --git a/deps/patches/gmp-config-ldflags.patch b/deps/patches/gmp-config-ldflags.patch new file mode 100644 index 0000000000000..fb89fa66b8da5 --- /dev/null +++ b/deps/patches/gmp-config-ldflags.patch @@ -0,0 +1,381 @@ +--- gmp-6.1.2/configure 2019-03-25 17:58:41.928471374 -0400 ++++ gmp-6.1.2-LDFLAGS/configure 2019-03-26 13:08:07.756316866 -0400 +@@ -5880,7 +5880,7 @@ if test "$gmp_prog_cc_works" = yes; then + int main () { return 0; } + EOF + echo "Test compile: " >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -5934,7 +5934,7 @@ void *f() { return g(); } + int main () { return 0; } + EOF + echo "Test compile: function pointer return" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -5990,7 +5990,7 @@ int cmov () { return (n >= 0 ? n : 0); } + int main () { return 0; } + EOF + echo "Test compile: cmov instruction" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6047,7 +6047,7 @@ unsigned long gcc303 () { return (unsign + int main () { return 0; } + EOF + echo "Test compile: double -> ulong conversion" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6102,7 +6102,7 @@ unsigned long fneg () { return -fneg_dat + int main () { return 0; } + EOF + echo "Test compile: double negation" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6158,7 +6158,7 @@ float ftod () { return (float) ftod_data + int main () { return 0; } + EOF + echo "Test compile: double -> float conversion" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6243,7 +6243,7 @@ param_init () + int main () { return 0; } + EOF + echo "Test compile: gnupro alpha ev6 char spilling" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6294,7 +6294,7 @@ if test "$gmp_prog_cc_works" = yes; then + int k; int foo () { __builtin_alloca (k); } + EOF + echo "Test compile: __builtin_alloca availability" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6340,7 +6340,7 @@ int foo () + int main () { return 0; } + EOF + echo "Test compile: alloca array" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6418,7 +6418,7 @@ int f () + int main () { return 0; } + EOF + echo "Test compile: abs int -> double conversion" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6483,7 +6483,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: long long reliability test 1" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6544,7 +6544,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: long long reliability test 2" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6605,7 +6605,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: freebsd hacked gcc" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6704,7 +6704,7 @@ main () + + EOF + echo "Test compile: mpn_lshift_com optimization" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -6813,7 +6813,7 @@ main () + + EOF + echo "Test compile: mpn_lshift_com optimization 2" >&5 +- gmp_compile="$cc $cflags $cppflags conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7325,7 +7325,7 @@ _main: + xorl %eax, %eax + ret + EOF +- gmp_compile="$cc $cflags $cppflags conftest.s -o conftest >&5" ++ gmp_compile="$cc $cflags $cppflags $LDFLAGS conftest.s -o conftest >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7390,7 +7390,7 @@ $as_echo_n "checking compiler $cc $cflag + cat >conftest.c <&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7498,7 +7498,7 @@ if test "$gmp_prog_cc_works" = yes; then + int main () { return 0; } + EOF + echo "Test compile: " >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7552,7 +7552,7 @@ void *f() { return g(); } + int main () { return 0; } + EOF + echo "Test compile: function pointer return" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7608,7 +7608,7 @@ int cmov () { return (n >= 0 ? n : 0); } + int main () { return 0; } + EOF + echo "Test compile: cmov instruction" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7665,7 +7665,7 @@ unsigned long gcc303 () { return (unsign + int main () { return 0; } + EOF + echo "Test compile: double -> ulong conversion" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7720,7 +7720,7 @@ unsigned long fneg () { return -fneg_dat + int main () { return 0; } + EOF + echo "Test compile: double negation" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7776,7 +7776,7 @@ float ftod () { return (float) ftod_data + int main () { return 0; } + EOF + echo "Test compile: double -> float conversion" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7861,7 +7861,7 @@ param_init () + int main () { return 0; } + EOF + echo "Test compile: gnupro alpha ev6 char spilling" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7912,7 +7912,7 @@ if test "$gmp_prog_cc_works" = yes; then + int k; int foo () { __builtin_alloca (k); } + EOF + echo "Test compile: __builtin_alloca availability" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -7958,7 +7958,7 @@ int foo () + int main () { return 0; } + EOF + echo "Test compile: alloca array" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8036,7 +8036,7 @@ int f () + int main () { return 0; } + EOF + echo "Test compile: abs int -> double conversion" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8101,7 +8101,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: long long reliability test 1" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8162,7 +8162,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: long long reliability test 2" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8223,7 +8223,7 @@ int dummy; + int main () { return 0; } + EOF + echo "Test compile: freebsd hacked gcc" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8322,7 +8322,7 @@ main () + + EOF + echo "Test compile: mpn_lshift_com optimization" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -8431,7 +8431,7 @@ main () + + EOF + echo "Test compile: mpn_lshift_com optimization 2" >&5 +- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" ++ gmp_compile="$cc $cflags $cppflags $flag $LDFLAGS conftest.c >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -9987,7 +9987,7 @@ main () + return 0; + } + EOF +-gmp_compile="$CC_FOR_BUILD conftest.c" ++gmp_compile="$CC_FOR_BUILD $LDFLAGS conftest.c" + cc_for_build_works=no + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 +@@ -10019,7 +10019,7 @@ main () + return 0; + } + EOF +-gmp_compile="$HOST_CC conftest.c" ++gmp_compile="$HOST_CC $LDFLAGS conftest.c" + cc_for_build_works=no + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 +@@ -10052,7 +10052,7 @@ main () + return 0; + } + EOF +-gmp_compile="$i conftest.c" ++gmp_compile="$i $LDFLAGS conftest.c" + cc_for_build_works=no + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 +@@ -10132,7 +10132,7 @@ main () + } + EOF + for i in .exe ,ff8 ""; do +- gmp_compile="$CC_FOR_BUILD conftest.c -o conftest$i" ++ gmp_compile="$CC_FOR_BUILD $LDFLAGS conftest.c -o conftest$i" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -10168,7 +10168,7 @@ main (int argc, char **argv) + return 0; + } + EOF +-gmp_compile="$CC_FOR_BUILD conftest.c" ++gmp_compile="$CC_FOR_BUILD $LDFLAGS conftest.c" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -10210,7 +10210,7 @@ foo () + return log (d); + } + EOF +-gmp_compile="$CC_FOR_BUILD conftest.c -lm" ++gmp_compile="$CC_FOR_BUILD $LDFLAGS conftest.c -lm" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? +@@ -10543,7 +10543,7 @@ if test "$gmp_prog_cxx_works" = yes; the + int main (void) { return 0; } + EOF + echo "Test compile: " >&5 +- gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5" ++ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS $LDFLAGS conftest.cc >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5 + (eval $gmp_cxxcompile) 2>&5 + ac_status=$? +@@ -10583,7 +10583,7 @@ using namespace foo; + int main (void) { return 0; } + EOF + echo "Test compile: namespace" >&5 +- gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5" ++ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS $LDFLAGS conftest.cc >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5 + (eval $gmp_cxxcompile) 2>&5 + ac_status=$? +@@ -10629,7 +10629,7 @@ void someoutput (void) { std::cout << 12 + int main (void) { return 0; } + EOF + echo "Test compile: std iostream" >&5 +- gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5" ++ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS $LDFLAGS conftest.cc >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5 + (eval $gmp_cxxcompile) 2>&5 + ac_status=$? +@@ -27095,7 +27095,7 @@ for tmp_underscore in "" "_"; do + ${tmp_gsym_prefix}main$gmp_cv_asm_label_suffix + addl $ ${tmp_underscore}_GLOBAL_OFFSET_TABLE_, %ebx + EOF +- gmp_compile="$CCAS $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.s >&5 && $CC $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.$OBJEXT >&5" ++ gmp_compile="$CCAS $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.s >&5 && $CC $CFLAGS $CPPFLAGS $LDFLAGS $lt_prog_compiler_pic conftest.$OBJEXT >&5" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 + (eval $gmp_compile) 2>&5 + ac_status=$? + diff --git a/src/crc32c.c b/src/crc32c.c index f9100a22abe93..9ad1991d3c804 100644 --- a/src/crc32c.c +++ b/src/crc32c.c @@ -43,6 +43,7 @@ #include "julia.h" #include "julia_internal.h" +#include "processor.h" #ifdef _CPU_AARCH64_ # include @@ -333,7 +334,7 @@ JL_DLLEXPORT uint32_t jl_crc32c(uint32_t crc, const char *buf, size_t len) # else static crc32c_func_t crc32c_dispatch(unsigned long hwcap) { - if (hwcap & HWCAP_CRC32) + if (hwcap & (1 << JL_AArch64_crc)) return crc32c_armv8; return jl_crc32c_sw; } diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 15c33f86524cd..06664623dc7f5 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -1101,7 +1101,8 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip for (size_t i = 0; i < sysimg_fptrs.nclones; i++) { if (diff == sysimg_fptrs.clone_offsets[i]) { uint32_t idx = sysimg_fptrs.clone_idxs[i] & jl_sysimg_val_mask; - frame0->linfo = sysimg_fvars_linfo[idx]; + if (idx < sysimg_fvars_n) // items after this were cloned but not referenced directly by a method (such as our ccall PLT thunks) + frame0->linfo = sysimg_fvars_linfo[idx]; break; } } diff --git a/src/disasm.cpp b/src/disasm.cpp index c7f74765cba65..bff8dd91f697a 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -628,24 +628,23 @@ static void jl_dump_asm_internal( { // GC safe // Get the host information - std::string TripleName = sys::getDefaultTargetTriple(); - Triple TheTriple(Triple::normalize(TripleName)); + Triple TheTriple(sys::getProcessTriple()); const auto &target = jl_get_llvm_disasm_target(); const auto &cpu = target.first; const auto &features = target.second; std::string err; - const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, err); + const Target *TheTarget = TargetRegistry::lookupTarget(TheTriple.str(), err); // Set up required helpers and streamer std::unique_ptr Streamer; SourceMgr SrcMgr; - std::unique_ptr MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName)); + std::unique_ptr MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TheTriple.str()), TheTriple.str())); assert(MAI && "Unable to create target asm info!"); - std::unique_ptr MRI(TheTarget->createMCRegInfo(TripleName)); + std::unique_ptr MRI(TheTarget->createMCRegInfo(TheTriple.str())); assert(MRI && "Unable to create target register info!"); std::unique_ptr MOFI(new MCObjectFileInfo()); @@ -659,16 +658,15 @@ static void jl_dump_asm_internal( // Set up Subtarget and Disassembler std::unique_ptr - STI(TheTarget->createMCSubtargetInfo(TripleName, cpu, features)); + STI(TheTarget->createMCSubtargetInfo(TheTriple.str(), cpu, features)); std::unique_ptr DisAsm(TheTarget->createMCDisassembler(*STI, Ctx)); if (!DisAsm) { - jl_printf(JL_STDERR, "ERROR: no disassembler for target %s\n", - TripleName.c_str()); + rstream << "ERROR: no disassembler for target " << TheTriple.str(); return; } unsigned OutputAsmVariant = 0; // ATT or Intel-style assembly - if (strcmp(asm_variant, "intel")==0) { + if (strcmp(asm_variant, "intel") == 0) { OutputAsmVariant = 1; } bool ShowEncoding = false; diff --git a/src/dump.c b/src/dump.c index 0e355b87a4c5c..5b481dedd9870 100644 --- a/src/dump.c +++ b/src/dump.c @@ -255,7 +255,7 @@ static int type_parameter_recursively_external(jl_value_t *p0) return 0; if (module_in_worklist(p->name->module)) return 0; - if (p->name->wrapper != (jl_value_t*)p0) { + if (jl_unwrap_unionall(p->name->wrapper) != (jl_value_t*)p) { if (!type_recursively_external(p)) return 0; } @@ -743,7 +743,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li else if (jl_is_unionall(v)) { write_uint8(s->s, TAG_UNIONALL); jl_datatype_t *d = (jl_datatype_t*)jl_unwrap_unionall(v); - if (jl_is_datatype(d) && d->name->wrapper == v && + if (jl_is_datatype(d) && jl_unwrap_unionall(d->name->wrapper) == (jl_value_t*)d && !module_in_worklist(d->name->module)) { write_uint8(s->s, 1); jl_serialize_value(s, d->name->module); diff --git a/src/gf.c b/src/gf.c index 194526ef7c7e7..c68e20a449e77 100644 --- a/src/gf.c +++ b/src/gf.c @@ -35,28 +35,6 @@ JL_DLLEXPORT size_t jl_get_tls_world_age(void) return jl_get_ptls_states()->world_age; } -JL_DLLEXPORT jl_value_t *jl_invoke(jl_method_instance_t *meth, jl_value_t **args, uint32_t nargs) -{ - jl_callptr_t fptr = meth->invoke; - if (fptr != jl_fptr_trampoline) { - return fptr(meth, args, nargs); - } - else { - // if this hasn't been inferred (compiled) yet, - // inferring it might not be able to handle the world range - // so we just do a generic apply here - // because that might actually be faster - // since it can go through the unrolled caches for this world - // and if inference is successful, this meth would get updated anyways, - // and we'll get the fast path here next time - - // TODO: if `meth` came from an `invoke` call, we should make sure - // meth->def is called instead of doing normal dispatch. - - return jl_apply(args, nargs); - } -} - /// ----- Handling for Julia callbacks ----- /// JL_DLLEXPORT int8_t jl_is_in_pure_context(void) @@ -2200,6 +2178,8 @@ JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types, size_t world) return (jl_value_t*)entry; } +jl_value_t *jl_gf_invoke_by_method(jl_method_t *method, jl_value_t **args, size_t nargs); + // invoke() // this does method dispatch with a set of types to match other than the // types of the actual arguments. this means it sometimes does NOT call the @@ -2212,13 +2192,10 @@ JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types, size_t world) jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) { size_t world = jl_get_ptls_states()->world_age; - jl_svec_t *tpenv = jl_emptysvec; - jl_tupletype_t *tt = NULL; jl_value_t *types = NULL; - JL_GC_PUSH3(&types, &tpenv, &tt); + JL_GC_PUSH1(&types); jl_value_t *gf = args[0]; types = jl_argtype_with_function(gf, types0); - jl_methtable_t *mt = jl_gf_mtable(gf); jl_typemap_entry_t *entry = (jl_typemap_entry_t*)jl_gf_invoke_lookup(types, world); if ((jl_value_t*)entry == jl_nothing) { @@ -2228,10 +2205,19 @@ jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) // now we have found the matching definition. // next look for or create a specialization of this definition. + JL_GC_POP(); + return jl_gf_invoke_by_method(entry->func.method, args, nargs); +} - jl_method_t *method = entry->func.method; +jl_value_t *jl_gf_invoke_by_method(jl_method_t *method, jl_value_t **args, size_t nargs) +{ + size_t world = jl_get_ptls_states()->world_age; jl_method_instance_t *mfunc = NULL; jl_typemap_entry_t *tm = NULL; + jl_methtable_t *mt = jl_gf_mtable(args[0]); + jl_svec_t *tpenv = jl_emptysvec; + jl_tupletype_t *tt = NULL; + JL_GC_PUSH2(&tpenv, &tt); if (method->invokes.unknown != NULL) tm = jl_typemap_assoc_exact(method->invokes, args, nargs, jl_cachearg_offset(mt), world); if (tm) { @@ -2248,7 +2234,7 @@ jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t **args, size_t nargs) if (method->invokes.unknown == NULL) method->invokes.unknown = jl_nothing; - mfunc = cache_method(mt, &method->invokes, entry->func.value, tt, method, world, tpenv, 1); + mfunc = cache_method(mt, &method->invokes, (jl_value_t*)method, tt, method, world, tpenv, 1); JL_UNLOCK(&method->writelock); } JL_GC_POP(); @@ -2303,6 +2289,33 @@ JL_DLLEXPORT jl_value_t *jl_get_invoke_lambda(jl_methtable_t *mt, return (jl_value_t*)mfunc; } +JL_DLLEXPORT jl_value_t *jl_invoke(jl_method_instance_t *meth, jl_value_t **args, uint32_t nargs) +{ + jl_callptr_t fptr = meth->invoke; + if (fptr != jl_fptr_trampoline) { + return fptr(meth, args, nargs); + } + else { + // if this hasn't been inferred (compiled) yet, + // inferring it might not be able to handle the world range + // so we just do a generic apply here + // because that might actually be faster + // since it can go through the unrolled caches for this world + // and if inference is successful, this meth would get updated anyways, + // and we'll get the fast path here next time + + jl_method_instance_t *mfunc = jl_lookup_generic_(args, nargs, + jl_int32hash_fast(jl_return_address()), + jl_get_ptls_states()->world_age); + // check whether `jl_apply_generic` would call the right method + if (mfunc->def.method == meth->def.method) + return mfunc->invoke(mfunc, args, nargs); + + // no; came from an `invoke` call + return jl_gf_invoke_by_method(meth->def.method, args, nargs); + } +} + // Return value is rooted globally jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_t *module, jl_datatype_t *st, int iskw) { @@ -2395,6 +2408,12 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio closure->max_valid = ml->max_world; } } + // In some corner cases type intersection is conservative and returns something + // for intersect(A, B) even though A is a dispatch tuple and !(A <: B). + // For dispatch purposes in such a case we know there's no match. This check + // fixes issue #30394. + if (jl_is_dispatch_tupletype(closure->match.type) && !closure->match.issubty) + return 1; // a method is shadowed if type <: S <: m->sig where S is the // signature of another applicable method /* diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 5d9e99a9627d9..ce00f3b7cdb7f 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -396,6 +396,8 @@ (vararg (let ((l (if (null? pargl) '() (last pargl)))) (if (or (vararg? l) (varargexpr? l)) (list l) '()))) + ;; positional args with vararg + (pargl-all pargl) ;; positional args without vararg (pargl (if (null? vararg) pargl (butlast pargl))) ;; positional args with everything required; for use by the core function @@ -424,13 +426,7 @@ (filter nospecialize-meta? kargl))) ;; body statements (stmts (cdr body)) - (positional-sparams - (filter (lambda (s) - (let ((name (car s))) - (or (expr-contains-eq name (cons 'list pargl)) - (and (pair? vararg) (expr-contains-eq name (car vararg))) - (not (expr-contains-eq name (cons 'list kargl)))))) - sparams)) + (positional-sparams (filter-sparams (cons 'list pargl-all) sparams)) (keyword-sparams (filter (lambda (s) (not (any (lambda (p) (eq? (car p) (car s))) @@ -462,7 +458,7 @@ ;; call with no keyword args ,(method-def-expr- - name positional-sparams (append pargl vararg) + name positional-sparams pargl-all `(block ,@(without-generated prologue) ,(let (;; call mangled(vals..., [rest_kw,] pargs..., [vararg]...) @@ -478,9 +474,7 @@ ;; call with unsorted keyword args. this sorts and re-dispatches. ,(method-def-expr- - name - ;; remove sparams that don't occur, to avoid printing the warning twice - (filter-sparams (cons 'list argl) positional-sparams) + name positional-sparams `((|::| ;; if there are optional positional args, we need to be able to reference the function name ,(if (any kwarg? pargl) (gensy) UNUSED) @@ -2998,7 +2992,9 @@ f(x) = yt(x) (kill)) (cdr e))) (else - (mark-used e) + (if (eq? (car e) '=) + (visit (caddr e)) + (mark-used e)) (if (and (or (eq? (car e) '=) (and (eq? (car e) 'method) (length> e 2))) (has? unused (cadr e))) diff --git a/src/llvm-simdloop.cpp b/src/llvm-simdloop.cpp index 683d41d57cc68..d64a6a8ddf921 100644 --- a/src/llvm-simdloop.cpp +++ b/src/llvm-simdloop.cpp @@ -207,8 +207,9 @@ bool LowerSIMDLoop::markSIMDLoop(Module &M, Function *marker, bool ivdep) MDNode *n = L->getLoopID(); if (!n) { // Loop does not have a LoopID yet, so give it one. - n = MDNode::get(Lh->getContext(), ArrayRef(NULL)); - n->replaceOperandWith(0, n); + auto temp_n = MDNode::getTemporary(Lh->getContext(), ArrayRef(NULL)); + temp_n->replaceOperandWith(0, temp_n.get()); + n = MDNode::replaceWithPermanent(std::move(temp_n)); L->setLoopID(n); } diff --git a/src/staticdata.c b/src/staticdata.c index 0f1aa9d1356ae..85496b6d07ed3 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1015,6 +1015,7 @@ static void jl_update_all_fptrs(jl_serializer_state *s) for (i = 0; i < sysimg_fvars_max; i++) { uintptr_t val = (uintptr_t)&linfos[i]; uint32_t offset = load_uint32(&val); + linfos[i] = NULL; if (offset != 0) { int specfunc = 1; if (offset & ((uintptr_t)1 << (8 * sizeof(uint32_t) - 1))) { diff --git a/src/support/strtod.c b/src/support/strtod.c index 047d404d90cda..225f2dbd4c933 100644 --- a/src/support/strtod.c +++ b/src/support/strtod.c @@ -118,9 +118,16 @@ JL_DLLEXPORT double jl_strtod_c(const char *nptr, char **endptr) decimal_point_pos = NULL; + p = nptr; + + /* parse leading spaces */ + while (isspace((unsigned char)*p)) { + p++; + } + /* Parse infinities and nans */ - val = parse_inf_or_nan(nptr, endptr); - if (*endptr != nptr) + val = parse_inf_or_nan(p, endptr); + if (*endptr != p) return val; /* Set errno to zero, so that we can distinguish zero results @@ -130,12 +137,6 @@ JL_DLLEXPORT double jl_strtod_c(const char *nptr, char **endptr) /* We process the optional sign manually, then pass the remainder to the system strtod. This ensures that the result of an underflow has the correct sign. */ - p = nptr; - - /* parse leading spaces */ - while (isspace((unsigned char)*p)) { - p++; - } /* Process leading sign, if present */ if (*p == '-') { diff --git a/stdlib/Distributed/src/macros.jl b/stdlib/Distributed/src/macros.jl index 15faadb3c31fa..4285073ec90a3 100644 --- a/stdlib/Distributed/src/macros.jl +++ b/stdlib/Distributed/src/macros.jl @@ -135,24 +135,17 @@ end extract_imports!(imports, x) = imports function extract_imports!(imports, ex::Expr) if Meta.isexpr(ex, (:import, :using)) - m = ex.args[1] - if isa(m, Expr) && m.head === :(:) - push!(imports, m.args[1].args[1]) - else - for a in ex.args - push!(imports, a.args[1]) - end - end + push!(imports, ex) elseif Meta.isexpr(ex, :let) extract_imports!(imports, ex.args[2]) elseif Meta.isexpr(ex, (:toplevel, :block)) - for i in eachindex(ex.args) - extract_imports!(imports, ex.args[i]) + for arg in ex.args + extract_imports!(imports, arg) end end return imports end -extract_imports(x) = extract_imports!(Symbol[], x) +extract_imports(x) = extract_imports!(Any[], x) """ @everywhere [procs()] expr @@ -183,7 +176,7 @@ macro everywhere(ex) end macro everywhere(procs, ex) - imps = [Expr(:import, m) for m in extract_imports(ex)] + imps = extract_imports(ex) return quote $(isempty(imps) ? nothing : Expr(:toplevel, imps...)) # run imports locally first let ex = $(Expr(:quote, ex)), procs = $(esc(procs)) diff --git a/stdlib/Distributed/test/distributed_exec.jl b/stdlib/Distributed/test/distributed_exec.jl index 383a6783a311d..aa462b73f0549 100644 --- a/stdlib/Distributed/test/distributed_exec.jl +++ b/stdlib/Distributed/test/distributed_exec.jl @@ -8,7 +8,7 @@ import Distributed: launch, manage include(joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testenv.jl")) @test Distributed.extract_imports(:(begin; import Foo, Bar; let; using Baz; end; end)) == - [:Foo, :Bar, :Baz] + Any[:(import Foo, Bar), :(using Baz)] # Test a few "remote" invocations when no workers are present @test remote(myid)() == 1 diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index 1a5eca3c0ce05..f5714e6444170 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -168,7 +168,7 @@ end function rmul!(A::AbstractMatrix, D::Diagonal) @assert !has_offset_axes(A) - A .= A .* transpose(D.diag) + A .= A .* permutedims(D.diag) return A end @@ -256,20 +256,20 @@ lmul!(A::Diagonal, B::Diagonal) = Diagonal(B.diag .= A.diag .* B.diag) function lmul!(adjA::Adjoint{<:Any,<:Diagonal}, B::AbstractMatrix) A = adjA.parent - return lmul!(conj(A.diag), B) + return lmul!(adjoint(A), B) end function lmul!(transA::Transpose{<:Any,<:Diagonal}, B::AbstractMatrix) A = transA.parent - return lmul!(A.diag, B) + return lmul!(transpose(A), B) end function rmul!(A::AbstractMatrix, adjB::Adjoint{<:Any,<:Diagonal}) B = adjB.parent - return rmul!(A, conj(B.diag)) + return rmul!(A, adjoint(B)) end function rmul!(A::AbstractMatrix, transB::Transpose{<:Any,<:Diagonal}) B = transB.parent - return rmul!(A, B.diag) + return rmul!(A, transpose(B)) end # Get ambiguous method if try to unify AbstractVector/AbstractMatrix here using AbstractVecOrMat @@ -508,10 +508,9 @@ end *(x::Adjoint{<:Any,<:AbstractVector}, D::Diagonal) = Adjoint(map((t,s) -> t'*s, D.diag, parent(x))) *(x::Adjoint{<:Any,<:AbstractVector}, D::Diagonal, y::AbstractVector) = mapreduce(t -> t[1]*t[2]*t[3], +, zip(x, D.diag, y)) -*(x::Transpose{<:Any,<:AbstractVector}, D::Diagonal) = Transpose(map(*, D.diag, parent(x))) +*(x::Transpose{<:Any,<:AbstractVector}, D::Diagonal) = Transpose(map((t,s) -> transpose(t)*s, D.diag, parent(x))) *(x::Transpose{<:Any,<:AbstractVector}, D::Diagonal, y::AbstractVector) = mapreduce(t -> t[1]*t[2]*t[3], +, zip(x, D.diag, y)) -# TODO: these methods will yield row matrices, rather than adjoint/transpose vectors function cholesky!(A::Diagonal, ::Val{false} = Val(false); check::Bool = true) info = 0 diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index ee11b5db9854b..e420d5bc6de28 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -441,10 +441,20 @@ end fullBB = copyto!(Matrix{Matrix{T}}(undef, 2, 2), BB) for (transform1, transform2) in ((identity, identity), (identity, adjoint ), (adjoint, identity ), (adjoint, adjoint ), - (identity, transpose), (transpose, identity ), (transpose, transpose) ) + (identity, transpose), (transpose, identity ), (transpose, transpose), + (identity, Adjoint ), (Adjoint, identity ), (Adjoint, Adjoint ), + (identity, Transpose), (Transpose, identity ), (Transpose, Transpose)) @test *(transform1(D), transform2(B))::typeof(D) ≈ *(transform1(Matrix(D)), transform2(Matrix(B))) atol=2 * eps() @test *(transform1(DD), transform2(BB))::typeof(DD) == *(transform1(fullDD), transform2(fullBB)) end + M = randn(T, 5, 5) + MM = [randn(T, 2, 2) for _ in 1:2, _ in 1:2] + for transform in (identity, adjoint, transpose, Adjoint, Transpose) + @test lmul!(transform(D), copy(M)) == *(transform(Matrix(D)), M) + @test rmul!(copy(M), transform(D)) == *(M, transform(Matrix(D))) + @test lmul!(transform(DD), copy(MM)) == *(transform(fullDD), MM) + @test rmul!(copy(MM), transform(DD)) == *(MM, transform(fullDD)) + end end end @@ -454,10 +464,16 @@ end end @testset "Multiplication with Adjoint and Transpose vectors (#26863)" begin - x = rand(5) - D = Diagonal(rand(5)) - @test x'*D*x == (x'*D)*x == (x'*Array(D))*x - @test Transpose(x)*D*x == (Transpose(x)*D)*x == (Transpose(x)*Array(D))*x + x = collect(1:2) + xt = transpose(x) + A = reshape([[1 2; 3 4], zeros(Int,2,2), zeros(Int, 2, 2), [5 6; 7 8]], 2, 2) + D = Diagonal(A) + @test x'*D == x'*A == copy(x')*D == copy(x')*A + @test xt*D == xt*A == copy(xt)*D == copy(xt)*A + y = [x, x] + yt = transpose(y) + @test y'*D*y == (y'*D)*y == (y'*A)*y + @test yt*D*y == (yt*D)*y == (yt*A)*y end @testset "Triangular division by Diagonal #27989" begin diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 041775d63ada3..9a50cd1a7b48f 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,2 +1,2 @@ PKG_BRANCH = master -PKG_SHA1 = 93b6d6de857dc88e665d2c64397852ab9701ba24 +PKG_SHA1 = 1609a05aee5d5960670738d8d834d91235bd6b1e diff --git a/stdlib/Profile/src/Profile.jl b/stdlib/Profile/src/Profile.jl index 5cb34e132942f..8ae9542c2c2f4 100644 --- a/stdlib/Profile/src/Profile.jl +++ b/stdlib/Profile/src/Profile.jl @@ -514,6 +514,7 @@ function tree!(root::StackFrameTree{T}, all::Vector{UInt64}, lidict::Union{LineI # jump forward to the end of the inlining chain # avoiding an extra (slow) lookup of `ip` in `lidict` # and an extra chain of them in `down` + # note that we may even have this === parent (if we're ignoring this frame ip) this = builder_value[fastkey] let this = this while this !== parent @@ -532,8 +533,7 @@ function tree!(root::StackFrameTree{T}, all::Vector{UInt64}, lidict::Union{LineI frame = (frames isa Vector ? frames[i] : frames) !C && frame.from_c && continue key = (T === UInt64 ? ip : frame) - down = parent.down - this = get!(down, key) do + this = get!(parent.down, key) do return StackFrameTree{T}() end this.frame = frame diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index fec6faac88734..c5ef01fe74a0b 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -353,7 +353,7 @@ get_value(sym, fn) = (sym, true) function get_value_getfield(ex::Expr, fn) # Example :((top(getfield))(Base,:max)) val, found = get_value_getfield(ex.args[2],fn) #Look up Base in Main and returns the module - found || return (nothing, false) + (found && length(ex.args) >= 3) || return (nothing, false) return get_value_getfield(ex.args[3], val) #Look up max in Base and returns the function if found. end get_value_getfield(sym, fn) = get_value(sym, fn) @@ -407,7 +407,7 @@ function try_get_type(sym::Expr, fn::Module) elseif sym.head === :ref # some simple cases of `expand` return try_get_type(Expr(:call, GlobalRef(Base, :getindex), sym.args...), fn) - elseif sym.head === :. + elseif sym.head === :. && sym.args[2] isa QuoteNode # second check catches broadcasting return try_get_type(Expr(:call, GlobalRef(Core, :getfield), sym.args...), fn) end return (Any, false) @@ -432,10 +432,21 @@ function complete_methods(ex_org::Expr, context_module=Main)::Vector{Completion} args_ex = Any[] func, found = get_value(ex_org.args[1], context_module) !found && return Completion[] - for ex in ex_org.args[2:end] - val, found = get_type(ex, context_module) - push!(args_ex, val) + + funargs = ex_org.args[2:end] + # handle broadcasting, but only handle number of arguments instead of + # argument types + if ex_org.head === :. && ex_org.args[2] isa Expr + for _ in ex_org.args[2].args + push!(args_ex, Any) + end + else + for ex in funargs + val, found = get_type(ex, context_module) + push!(args_ex, val) + end end + out = Completion[] t_in = Tuple{Core.Typeof(func), args_ex...} # Input types na = length(args_ex)+1 @@ -610,12 +621,16 @@ function completions(string, pos, context_module=Main)::Completions # Make sure that only bslash_completions is working on strings inc_tag==:string && return String[], 0:-1, false - if inc_tag == :other && should_method_complete(partial) frange, method_name_end = find_start_brace(partial) ex = Meta.parse(partial[frange] * ")", raise=false, depwarn=false) - if isa(ex, Expr) && ex.head==:call - return complete_methods(ex, context_module), first(frange):method_name_end, false + + if isa(ex, Expr) + if ex.head==:call + return complete_methods(ex, context_module), first(frange):method_name_end, false + elseif ex.head==:. && ex.args[2] isa Expr && ex.args[2].head==:tuple + return complete_methods(ex, context_module), first(frange):(method_name_end - 1), false + end end elseif inc_tag == :comment return Completion[], 0:-1, false diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index ebb2dcbd70d0d..1a2944cba985b 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -21,13 +21,13 @@ helpmode(line::AbstractString) = helpmode(stdout, line) function _helpmode(io::IO, line::AbstractString) line = strip(line) + x = Meta.parse(line, raise = false, depwarn = false) expr = - if haskey(keywords, Symbol(line)) + if haskey(keywords, Symbol(line)) || isexpr(x, :error) || isexpr(x, :invalid) # Docs for keywords must be treated separately since trying to parse a single # keyword such as `function` would throw a parse error due to the missing `end`. Symbol(line) else - x = Meta.parse(line, raise = false, depwarn = false) # Retrieving docs for macros requires us to make a distinction between the text # `@macroname` and `@macroname()`. These both parse the same, but are used by # the docsystem to return different results. The first returns all documentation diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 2a290eb2ec3d3..9404d16d25f2b 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -972,6 +972,12 @@ for (line, expr) in Pair[ @test Base.eval(REPL._helpmode(buf, line)) isa Union{Markdown.MD,Nothing} end +# PR 30754, Issues #22013, #24871, #26933, #29282, #29361, #30348 +for line in ["′", "abstract", "type", "|=", ".="] + @test occursin("No documentation found.", + sprint(show, Base.eval(REPL._helpmode(IOBuffer(), line))::Union{Markdown.MD,Nothing})) +end + # PR #27562 fake_repl() do stdin_write, stdout_read, repl repltask = @async begin diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 15bcc527c6953..eb19f8d60097b 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -960,6 +960,16 @@ let s = "type_test.xx.y" @test s[r] == "y" end +let s = ":(function foo(::Int) end).args[1].args[2]." + c, r = test_complete_context(s) + @test c == Any[] +end + +let s = "log(log.(x)," + c, r = test_complete_context(s) + @test !isempty(c) +end + let s = "Base.return_types(getin" c, r = test_complete_context(s) @test "getindex" in c @@ -981,6 +991,14 @@ let s = "test(1,1, " @test s[r] == "test" end +let s = "test.(1,1, " + c, r, res = test_complete_context(s) + @test !res + @test length(c) == 4 + @test r == 1:4 + @test s[r] == "test" +end + let s = "prevind(\"θ\",1," c, r, res = test_complete_context(s) @test c[1] == string(first(methods(prevind, Tuple{String, Int}))) diff --git a/stdlib/SHA/test/runtests.jl b/stdlib/SHA/test/runtests.jl index 63a333bdf779d..ce0d2b68fdbac 100644 --- a/stdlib/SHA/test/runtests.jl +++ b/stdlib/SHA/test/runtests.jl @@ -9,7 +9,8 @@ const VERBOSE = false lorem = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." so_many_as_array = repeat([0x61], 1000000) so_many_as_tuple = ntuple((i) -> 0x61, 1000000) -file = ".sha" # Subject to change +tempdir = mktempdir() +file = joinpath(tempdir, ".sha") fIO = open(file, "w") write(fIO, '\0') close(fIO) @@ -274,16 +275,24 @@ end # test error if eltype of input is not UInt8 for f in sha_funcs global nerrors + data = UInt32[0x23467, 0x324775] try - f(UInt32[0x23467, 0x324775]) - warn("Non-UInt8 Arrays should fail") - nerrors += 1 - catch + f(data) + catch ex + if ex isa MethodError && + ex.f === f && + ex.args === (data,) + continue + end + rethrow() end + warn("Non-UInt8 Arrays should fail") + nerrors += 1 end # Clean up the I/O mess rm(file) +rm(tempdir) if nerrors == 0 VERBOSE && println("ALL OK") diff --git a/stdlib/SparseArrays/src/higherorderfns.jl b/stdlib/SparseArrays/src/higherorderfns.jl index e09ca104c4220..68c267f1848dc 100644 --- a/stdlib/SparseArrays/src/higherorderfns.jl +++ b/stdlib/SparseArrays/src/higherorderfns.jl @@ -383,7 +383,7 @@ function _map_zeropres!(f::Tf, C::SparseVecOrMat, As::Vararg{SparseVecOrMat,N}) vals, ks, rows = _fusedupdate_all(rowsentinel, activerow, rows, ks, stopks, As) Cx = f(vals...) if !_iszero(Cx) - Ck > spaceC && (spaceC = expandstorage!(C, Ck + min(length(C), _sumnnzs(As...)) - (sum(ks) - N))) + Ck > spaceC && (spaceC = expandstorage!(C, min(length(C), Ck + _sumnnzs(As...) - (sum(ks) - N)))) storedinds(C)[Ck] = activerow storedvals(C)[Ck] = Cx Ck += 1 diff --git a/stdlib/SparseArrays/src/sparsematrix.jl b/stdlib/SparseArrays/src/sparsematrix.jl index 02c975168c6ec..81f23f3664e72 100644 --- a/stdlib/SparseArrays/src/sparsematrix.jl +++ b/stdlib/SparseArrays/src/sparsematrix.jl @@ -1558,12 +1558,22 @@ sparse(s::UniformScaling, dims::Dims{2}) = SparseMatrixCSC(s, dims) sparse(s::UniformScaling, m::Integer, n::Integer) = sparse(s, Dims((m, n))) # TODO: More appropriate location? -conj!(A::SparseMatrixCSC) = (@inbounds broadcast!(conj, A.nzval, A.nzval); A) -(-)(A::SparseMatrixCSC) = SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), map(-, A.nzval)) +function conj!(A::SparseMatrixCSC) + map!(conj, nzvalview(A), nzvalview(A)) + return A +end +function (-)(A::SparseMatrixCSC) + nzval = similar(A.nzval) + map!(-, view(nzval, 1:nnz(A)), nzvalview(A)) + return SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), nzval) +end # the rest of real, conj, imag are handled correctly via AbstractArray methods -conj(A::SparseMatrixCSC{<:Complex}) = - SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), conj(A.nzval)) +function conj(A::SparseMatrixCSC{<:Complex}) + nzval = similar(A.nzval) + map!(conj, view(nzval, 1:nnz(A)), nzvalview(A)) + return SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), nzval) +end imag(A::SparseMatrixCSC{Tv,Ti}) where {Tv<:Real,Ti} = spzeros(Tv, Ti, A.m, A.n) ## Binary arithmetic and boolean operators @@ -1968,8 +1978,8 @@ function getindex_cols(A::SparseMatrixCSC{Tv,Ti}, J::AbstractVector) where {Tv,T return SparseMatrixCSC(m, nJ, colptrS, rowvalS, nzvalS) end -getindex_traverse_col(::AbstractUnitRange, lo::Int, hi::Int) = lo:hi -getindex_traverse_col(I::StepRange, lo::Int, hi::Int) = step(I) > 0 ? (lo:1:hi) : (hi:-1:lo) +getindex_traverse_col(::AbstractUnitRange, lo::Integer, hi::Integer) = lo:hi +getindex_traverse_col(I::StepRange, lo::Integer, hi::Integer) = step(I) > 0 ? (lo:1:hi) : (hi:-1:lo) function getindex(A::SparseMatrixCSC{Tv,Ti}, I::AbstractRange, J::AbstractVector) where {Tv,Ti<:Integer} @assert !has_offset_axes(A, I, J) diff --git a/stdlib/SparseArrays/test/higherorderfns.jl b/stdlib/SparseArrays/test/higherorderfns.jl index 5871e2d96e1e2..2e1f1b6013771 100644 --- a/stdlib/SparseArrays/test/higherorderfns.jl +++ b/stdlib/SparseArrays/test/higherorderfns.jl @@ -632,4 +632,14 @@ end @test minimum(sparse([1, 2], [1, 2], ones(Int32, 2)), dims = 1) isa Matrix end +@testset "issue #31758: out of bounds write in _map_zeropres!" begin + y = sparsevec([2,7], [1., 2.], 10) + x1 = sparsevec(fill(1.0, 10)) + x2 = sparsevec([2,7], [1., 2.], 10) + x3 = sparsevec(fill(1.0, 10)) + f(x, y, z) = x == y == z == 0 ? 0.0 : NaN + y .= f.(x1, x2, x3) + @test all(isnan, y) +end + end # module diff --git a/stdlib/SparseArrays/test/sparse.jl b/stdlib/SparseArrays/test/sparse.jl index 416cbffac27cf..89fd7a5e66766 100644 --- a/stdlib/SparseArrays/test/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -92,6 +92,10 @@ do33 = fill(1.,3) end end +@testset "Issue #30006" begin + SparseMatrixCSC{Float64,Int32}(spzeros(3,3))[:, 1] == [1, 2, 3] +end + @testset "concatenation tests" begin sp33 = sparse(1.0I, 3, 3) @@ -709,6 +713,8 @@ end @test ss116[:,:] == copy(ss116) + @test convert(SparseMatrixCSC{Float32,Int32}, sd116)[2:5,:] == convert(SparseMatrixCSC{Float32,Int32}, sd116[2:5,:]) + # range indexing @test Array(ss116[i,:]) == aa116[i,:] @test Array(ss116[:,j]) == aa116[:,j] @@ -2307,4 +2313,16 @@ end @test m2.module == SparseArrays end +@testset "unary operations on matrices where length(nzval)>nnz" begin + # this should create a sparse matrix with length(nzval)>nnz + A = SparseMatrixCSC(Complex{BigInt}[1+im 2+2im]')'[1:1, 2:2] + # ...ensure it does! If necessary, the test needs to be updated to use + # another mechanism to create a suitable A. + @assert length(A.nzval) > nnz(A) + @test -A == fill(-2-2im, 1, 1) + @test conj(A) == fill(2-2im, 1, 1) + conj!(A) + @test A == fill(2-2im, 1, 1) +end + end # module diff --git a/stdlib/SuiteSparse/Project.toml b/stdlib/SuiteSparse/Project.toml index 8ea21106262c4..a851e081a383e 100644 --- a/stdlib/SuiteSparse/Project.toml +++ b/stdlib/SuiteSparse/Project.toml @@ -4,13 +4,14 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [extras] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] test = ["Test", "Random", "DelimitedFiles", "Serialization"] diff --git a/stdlib/SuiteSparse/src/umfpack.jl b/stdlib/SuiteSparse/src/umfpack.jl index a8eb90ed379c4..23c0708fb72d8 100644 --- a/stdlib/SuiteSparse/src/umfpack.jl +++ b/stdlib/SuiteSparse/src/umfpack.jl @@ -11,6 +11,8 @@ import LinearAlgebra: Factorization, det, lu, ldiv! using SparseArrays import SparseArrays: nnz +import Serialization: AbstractSerializer, deserialize + import ..increment, ..increment!, ..decrement, ..decrement! include("umfpack_h.jl") @@ -192,6 +194,22 @@ function show(io::IO, F::UmfpackLU) F.numeric != C_NULL && print(io, '\n', F.numeric) end +function deserialize(s::AbstractSerializer, t::Type{UmfpackLU{Tv,Ti}}) where {Tv,Ti} + symbolic = deserialize(s) + numeric = deserialize(s) + m = deserialize(s) + n = deserialize(s) + colptr = deserialize(s) + rowval = deserialize(s) + nzval = deserialize(s) + status = deserialize(s) + obj = UmfpackLU{Tv,Ti}(symbolic, numeric, m, n, colptr, rowval, nzval, status) + + finalizer(umfpack_free_symbolic, obj) + + return obj +end + ## Wrappers for UMFPACK functions # generate the name of the C function according to the value and integer types diff --git a/stdlib/SuiteSparse/test/umfpack.jl b/stdlib/SuiteSparse/test/umfpack.jl index 1683f21aa4aab..356c0cf3fa4e7 100644 --- a/stdlib/SuiteSparse/test/umfpack.jl +++ b/stdlib/SuiteSparse/test/umfpack.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using SuiteSparse: increment! +using Serialization using LinearAlgebra: Adjoint, Transpose, SingularException @testset "UMFPACK wrappers" begin @@ -176,4 +177,16 @@ using LinearAlgebra: Adjoint, Transpose, SingularException end end + @testset "deserialization" begin + A = 10*I + sprandn(10, 10, 0.4) + F1 = lu(A) + b = IOBuffer() + serialize(b, F1) + seekstart(b) + F2 = deserialize(b) + for nm in (:colptr, :m, :n, :nzval, :rowval, :status) + @test getfield(F1, nm) == getfield(F2, nm) + end + end + end diff --git a/test/compiler/compiler.jl b/test/compiler/compiler.jl index 01b7000a6a68a..791c73a61f7db 100644 --- a/test/compiler/compiler.jl +++ b/test/compiler/compiler.jl @@ -1822,6 +1822,15 @@ function g15276() end @test g15276() isa Vector{Int} +function inbounds_30563() + local y + @inbounds for i in 1:10 + y = (m->2i)(0) + end + return y +end +@test Base.return_types(inbounds_30563, ()) == Any[Int] + # issue #27316 - inference shouldn't hang on these f27316(::Vector) = nothing f27316(::Any) = f27316(Any[][1]), f27316(Any[][1]) @@ -2068,3 +2077,24 @@ function f29036(s, i) val end @test Base.return_types(f29036, (String, Int)) == Any[Char] + +# issue #30394 +mutable struct Base30394 + a::Int +end + +mutable struct Foo30394 + foo_inner::Base30394 + Foo30394() = new(Base30394(1)) +end + +mutable struct Foo30394_2 + foo_inner::Foo30394 + Foo30394_2() = new(Foo30394()) +end + +f30394(foo::T1, ::Type{T2}) where {T2, T1 <: T2} = foo + +f30394(foo, T2) = f30394(foo.foo_inner, T2) + +@test Base.return_types(f30394, (Foo30394_2, Type{Base30394})) == Any[Base30394] diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl new file mode 100644 index 0000000000000..27269d132a9f2 --- /dev/null +++ b/test/compiler/irpasses.jl @@ -0,0 +1,51 @@ +# Tests for SROA + +mutable struct Foo30594; x::Float64; end +Base.copy(x::Foo30594) = Foo30594(x.x) +function add!(p::Foo30594, off::Foo30594) + p.x += off.x + return p +end +Base.:(+)(a::Foo30594, b::Foo30594) = add!(copy(a), b) + +let results = Float64[] + @noinline use30594(x) = push!(results, x.x); nothing + function foo30594(cnt::Int, dx::Int) + step = Foo30594(dx) + curr = step + Foo30594(1) + for i in 1:cnt + use30594(curr) + curr = curr + step + end + nothing + end + + foo30594(4, -1) + @test results == [0.0, -1.0, -2.0, -3.0] +end + +# Issue #29983 +# This one is a bit hard to trigger, but the key is to create a case +# where SROA needs to introduce an intermediate type-unstable phi node +struct Foo29983{T} + x::Tuple{T} +end +struct Bar29983{S} + x::S +end +Base.:+(a::T, b::Bar29983{S}) where {T, S} = Bar29983(a + b.x) +Base.:+(a::Bar29983{S}, b::T) where {T, S} = b + a +Base.:+(a::Bar29983{S}, b::Bar29983{T}) where {T, S} = Bar29983(a.x + b.x) +Base.:+(a::Foo29983, b::Foo29983) = Foo29983((a.x[1] + b.x[1],)) + +function f(x::Vector{T}) where {T} + x1 = Foo29983((x[1],)) + la1 = Foo29983((x[1],)) + f1 = Foo29983((0,)) + for _ in 1:2 + f1 += la1 + end + return f1 +end + +@test f([Bar29983(1.0)]).x[1].x == 2.0 diff --git a/test/copy.jl b/test/copy.jl index 74650d28d42d4..9b7dd82bdf03a 100644 --- a/test/copy.jl +++ b/test/copy.jl @@ -84,6 +84,9 @@ end @test c[1] === c[2] end +# issue #30911 +@test deepcopy(Array{Int,N} where N) == Array{Int,N} where N + # issue #14027 struct Nullable14027{T} hasvalue::Bool diff --git a/test/core.jl b/test/core.jl index ae9a90b5149ce..d1d4ff40bab0a 100644 --- a/test/core.jl +++ b/test/core.jl @@ -2432,6 +2432,20 @@ const T24460 = Tuple{T,T} where T g24460() = invoke(f24460, T24460, 1, 2) @test @inferred(g24460()) === 2.0 +# issue #30679 +@noinline function f30679(::DataType) + b = IOBuffer() + write(b, 0x00) + 2 +end +@noinline function f30679(t::Type{Int}) + x = invoke(f30679, Tuple{DataType}, t) + b = IOBuffer() + write(b, 0x00) + return x + 40 +end +@test f30679(Int) == 42 + call_lambda1() = (()->x)(1) call_lambda2() = ((x)->x)() call_lambda3() = ((x)->x)(1,2) diff --git a/test/iterators.jl b/test/iterators.jl index be5ad0b9398e5..ac33b611f3ed4 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -549,3 +549,27 @@ end @test ps isa Iterators.Pairs @test collect(ps) == [1 => :a, 2 => :b] end + +@testset "Stateful fix #30643" begin + @test Base.IteratorSize(1:10) isa Base.HasShape + a = Iterators.Stateful(1:10) + @test Base.IteratorSize(a) isa Base.HasLength + @test length(a) == 10 + @test length(collect(a)) == 10 + @test length(a) == 0 + b = Iterators.Stateful(Iterators.take(1:10,3)) + @test Base.IteratorSize(b) isa Base.HasLength + @test length(b) == 3 + @test length(collect(b)) == 3 + @test length(b) == 0 + c = Iterators.Stateful(Iterators.countfrom(1)) + @test Base.IteratorSize(c) isa Base.IsInfinite + @test length(Iterators.take(c,3)) == 3 + @test length(collect(Iterators.take(c,3))) == 3 + d = Iterators.Stateful(Iterators.filter(isodd,1:10)) + @test Base.IteratorSize(d) isa Base.SizeUnknown + @test length(collect(Iterators.take(d,3))) == 3 + @test length(collect(d)) == 2 + @test length(collect(d)) == 0 +end + diff --git a/test/keywordargs.jl b/test/keywordargs.jl index 51c6c60e83772..eacacdc2ea248 100644 --- a/test/keywordargs.jl +++ b/test/keywordargs.jl @@ -117,6 +117,17 @@ end @test kwf7(1.5;k=2.5) === Float64 @test_throws MethodError kwf7(1.5) @test_throws TypeError kwf7(1.5; k=2) + + # issue #30792 + g30792(a::C; b=R(1)) where {R <: Real, C <: Union{R, Complex{R}}} = R + @test g30792(1.0) === Float64 + @test g30792(1.0im) === Float64 + @test g30792(1.0im, b=1) === Float64 + @test_throws MethodError g30792("") + f30792(a::C; b::R=R(1)) where {R <: Real, C <: Union{R, Complex{R}}} = R + @test f30792(2im) === Int + @test f30792(2im, b=3) === Int + @test_throws TypeError f30792(2im, b=3.0) end # try to confuse it with quoted symbol kwf8(x::MIME{:T};k::T=0) where {T} = 0 diff --git a/test/offsetarray.jl b/test/offsetarray.jl index 5aa58853179eb..e98f90691b3d7 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -203,6 +203,8 @@ cmp_showf(Base.print_matrix, io, OffsetArray(rand(10^3,5), (10,-9))) # column cmp_showf(Base.print_matrix, io, OffsetArray(rand(5,10^3), (10,-9))) # rows fit cmp_showf(Base.print_matrix, io, OffsetArray(rand(10^3,10^3), (10,-9))) # neither fits cmp_showf(Base.print_matrix, io, OffsetArray(reshape(range(-0.212121212121, stop=2/11, length=3*29), 3, 29), (-2, -15)); options=(:displaysize=>(53,210),)) +cmp_showf(show, io, OffsetArray(collect(1:100), (100,))) # issue #31641 + targets1 = ["0-dimensional $OAs_name.OffsetArray{Float64,0,Array{Float64,0}}:\n1.0", "$OAs_name.OffsetArray{Float64,1,Array{Float64,1}} with indices 2:2:\n 1.0", "$OAs_name.OffsetArray{Float64,2,Array{Float64,2}} with indices 2:2×3:3:\n 1.0", diff --git a/test/parse.jl b/test/parse.jl index 5bf3b806edca8..d1c362d03b2f1 100644 --- a/test/parse.jl +++ b/test/parse.jl @@ -268,8 +268,8 @@ end # parsing complex numbers (#22250) @testset "complex parsing" begin - for r in (1,0,-1), i in (1,0,-1), sign in ('-','+'), Im in ("i","j","im") - for s1 in (""," "), s2 in (""," "), s3 in (""," "), s4 in (""," ") + for sign in ('-','+'), Im in ("i","j","im"), s1 in (""," "), s2 in (""," "), s3 in (""," "), s4 in (""," ") + for r in (1,0,-1), i in (1,0,-1), n = Complex(r, sign == '+' ? i : -i) s = string(s1, r, s2, sign, s3, i, Im, s4) @test n === parse(Complex{Int}, s) @@ -283,6 +283,13 @@ end @test n*parse(T,"1e-3") == parse(Complex{T}, string(s1, r, "e-3", s2, sign, s3, i, "e-3", Im, s4)) end end + for r in (-1.0,-1e-9,Inf,-Inf,NaN), i in (-1.0,-1e-9,Inf,NaN) + n = Complex(r, sign == '+' ? i : -i) + s = lowercase(string(s1, r, s2, sign, s3, i, Im, s4)) + @test n === parse(ComplexF64, s) + @test Complex(r) === parse(ComplexF64, string(s1, r, s2)) + @test Complex(0,i) === parse(ComplexF64, string(s3, i, Im, s4)) + end end @test parse(Complex{Float16}, "3.3+4i") === Complex{Float16}(3.3+4im) @test parse(Complex{Int}, SubString("xxxxxx1+2imxxxx", 7, 10)) === 1+2im @@ -311,3 +318,10 @@ end @test eltype([tryparse(Float64, s) for s in String[]]) == Union{Nothing, Float64} @test eltype([tryparse(Complex{Int}, s) for s in String[]]) == Union{Nothing, Complex{Int}} end + +@testset "inf and nan parsing" begin + for (v,vs) in ((NaN,"nan"), (Inf,"inf"), (Inf,"infinity")), sbefore in ("", " "), safter in ("", " "), sign in (+, -), case in (lowercase, uppercase) + s = case(string(sbefore, sign, vs, safter)) + @test isequal(parse(Float64, s), sign(v)) + end +end diff --git a/test/precompile.jl b/test/precompile.jl index 61e5e59512b5e..f9709de6916f9 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -744,5 +744,27 @@ let end end +# issue #29936 +let + load_path = mktempdir() + load_cache_path = mktempdir() + try + write(joinpath(load_path, "Foo29936.jl"), + """ + module Foo29936 + const global m = Val{nothing}() + const global h = Val{:hey}() + wab = [("a", m), ("b", h),] + end + """) + pushfirst!(LOAD_PATH, load_path) + pushfirst!(DEPOT_PATH, load_cache_path) + @eval using Foo29936 + @test [("Plan", Foo29936.m), ("Plan", Foo29936.h),] isa Vector{Tuple{String,Val}} + finally + rm(load_path, recursive=true) + rm(load_cache_path, recursive=true) + end +end end # !withenv diff --git a/test/ranges.jl b/test/ranges.jl index cfb41a477ebef..272cee9c50e39 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1406,6 +1406,20 @@ end @test @inferred(z4 .+ z4) === z4 end +@testset "Issue #30006" begin + @test Base.Slice(Base.OneTo(5))[Int32(1)] == Int32(1) + @test Base.Slice(Base.OneTo(3))[Int8(2)] == Int8(2) + @test Base.Slice(1:10)[Int32(2)] == Int32(2) + @test Base.Slice(1:10)[Int8(2)] == Int8(2) +end + +@testset "Issue #30006" begin + @test Base.Slice(Base.OneTo(5))[Int32(1)] == Int32(1) + @test Base.Slice(Base.OneTo(3))[Int8(2)] == Int8(2) + @test Base.Slice(1:10)[Int32(2)] == Int32(2) + @test Base.Slice(1:10)[Int8(2)] == Int8(2) +end + @testset "allocation of TwicePrecision call" begin 0:286.493442:360 0:286:360 diff --git a/test/reinterpretarray.jl b/test/reinterpretarray.jl index bdb588433dba9..4505c2db5dd09 100644 --- a/test/reinterpretarray.jl +++ b/test/reinterpretarray.jl @@ -160,3 +160,22 @@ let a = [0.1 0.2; 0.3 0.4], at = reshape([(i,i+1) for i = 1:2:8], 2, 2) r = reinterpret(Int, vt) @test r == OffsetArray(reshape(1:8, 2, 2, 2), (0, offsetvt...)) end + +@testset "potentially aliased copies" begin + buffer = UInt8[1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0] + mid = length(buffer) ÷ 2 + x1 = reinterpret(Int64, @view buffer[1:mid]) + x2 = reinterpret(Int64, @view buffer[mid+1:end]) + x1 .= x2 + @test x1 == x2 == [2] + @test x1[] === x2[] === Int64(2) +end + +# Test 0-dimensional Arrays +A = zeros(UInt32) +B = reinterpret(Int32,A) +@test size(B) == () +@test axes(B) == () +B[] = Int32(5) +@test B[] === Int32(5) +@test A[] === UInt32(5) diff --git a/test/sets.jl b/test/sets.jl index daddf0bc7bb8b..594c1f0f89087 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -613,6 +613,27 @@ end end end +@testset "optimized union! with max_values" begin + # issue #30315 + T = Union{Nothing, Bool} + @test Base.max_values(T) == 3 + d = Set{T}() + union!(d, (nothing, true, false)) + @test length(d) == 3 + @test d == Set((nothing, true, false)) + @test nothing in d + @test true in d + @test false in d + + for X = (Int8, Int16, Int32, Int64) + @test Base.max_values(Union{Nothing, X}) == (sizeof(X) < sizeof(Int) ? + 2^(8*sizeof(X)) + 1 : + typemax(Int)) + end + # this does not account for non-empty intersections of the unioned types + @test Base.max_values(Union{Int8,Int16}) == 2^8 + 2^16 +end + struct OpenInterval{T} lower::T upper::T diff --git a/test/strings/util.jl b/test/strings/util.jl index 17d1f9355006c..20de96ee9ce87 100644 --- a/test/strings/util.jl +++ b/test/strings/util.jl @@ -301,6 +301,7 @@ end @test chomp("foo\r\n") == "foo" @test chomp("fo∀\r\n") == "fo∀" @test chomp("fo∀") == "fo∀" + @test chop("") == "" @test chop("fooε") == "foo" @test chop("foεo") == "foε" @test chop("∃∃∃∃") == "∃∃∃"