diff --git a/.github/workflows/Typos.yml b/.github/workflows/Typos.yml index 833eb2dacbc9e..25cf9fea7cd0b 100644 --- a/.github/workflows/Typos.yml +++ b/.github/workflows/Typos.yml @@ -11,7 +11,7 @@ jobs: timeout-minutes: 5 steps: - name: Checkout the JuliaLang/julia repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Check spelling with typos diff --git a/.github/workflows/Whitespace.yml b/.github/workflows/Whitespace.yml index 30fb2fd5df1fc..3d0b8fe74d334 100644 --- a/.github/workflows/Whitespace.yml +++ b/.github/workflows/Whitespace.yml @@ -15,7 +15,7 @@ jobs: timeout-minutes: 2 steps: - name: Checkout the JuliaLang/julia repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - uses: julia-actions/setup-julia@5c9647d97b78a5debe5164e9eec09d653d29bd71 # v2.6.1 diff --git a/.github/workflows/cffconvert.yml b/.github/workflows/cffconvert.yml index 5dbf119426be5..45f19078a8af8 100644 --- a/.github/workflows/cffconvert.yml +++ b/.github/workflows/cffconvert.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out a copy of the repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 289247e17d0e0..afa95d7dbca36 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -22,7 +22,7 @@ function can_propagate_conditional(@nospecialize(rt), argtypes::Vector{Any}) return false end return isa(argtypes[rt.slot], Conditional) && - is_const_bool_or_bottom(rt.thentype) && is_const_bool_or_bottom(rt.thentype) + is_const_bool_or_bottom(rt.thentype) && is_const_bool_or_bottom(rt.elsetype) end function propagate_conditional(rt::InterConditional, cond::Conditional) diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index f7101d4319351..89b7de36fb26a 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -6531,4 +6531,18 @@ function haskey_inference_test() end @inferred haskey_inference_test() +# issue #60883: conditional propagation through wrapper functions +mutable struct A60883 + a::Int +end +inner60883(a, b) = iszero(a.a) && !b +outer60883(a, b) = inner60883(a, b) +function issue60883() + a = A60883(0) + b = iszero(a.a) + if outer60883(a, b) else end + return b # should not be narrowed to Const(false) +end +@test issue60883() === true + end # module inference diff --git a/NEWS.md b/NEWS.md index 8a2d55bacf9e5..dc596460b9d39 100644 --- a/NEWS.md +++ b/NEWS.md @@ -110,6 +110,11 @@ Deprecated or removed * The method `merge(combine::Callable, d::AbstractDict...)` is now deprecated to favor `mergewith` instead ([#59775]). +Deprecated or removed +--------------------- + +* The method `merge(combine::Callable, d::AbstractDict...)` is now deprecated to favor `mergewith` instead ([#59775]). + [#47102]: https://github.com/JuliaLang/julia/issues/47102 [#48507]: https://github.com/JuliaLang/julia/issues/48507 diff --git a/base/docs/Docs.jl b/base/docs/Docs.jl index 8817d82a6add6..95d80f30ba9f2 100644 --- a/base/docs/Docs.jl +++ b/base/docs/Docs.jl @@ -369,7 +369,7 @@ function metadata(__source__, __module__, expr, ismodule) if isa(eachex, Symbol) || isexpr(eachex, :(::)) # a field declaration if last_docstr !== nothing - push!(fields, P(namify(eachex), last_docstr)) + push!(fields, P(namify(eachex)::Symbol, last_docstr)) last_docstr = nothing end elseif isexpr(eachex, :function) || isexpr(eachex, :(=)) diff --git a/base/loading.jl b/base/loading.jl index 97200262be0bf..ed0761b00e827 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -261,7 +261,16 @@ struct LoadingCache located::Dict{Tuple{PkgId, Union{String, Nothing}}, Union{Tuple{String, String}, Nothing}} end const LOADING_CACHE = Ref{Union{LoadingCache, Nothing}}(nothing) # n.b.: all access to and through this are protected by require_lock -LoadingCache() = LoadingCache(load_path(), Dict(), Dict(), Dict(), Set(), Dict(), Dict(), Dict()) +LoadingCache() = LoadingCache( + load_path(), + Dict{String, UUID}(), + Dict{String, Union{Bool, String}}(), + Dict{String, Union{Nothing, String}}(), + Set{String}(), + Dict{Tuple{PkgId, String}, Union{Nothing, Tuple{PkgId, String}}}(), + Dict{String, Union{Nothing, Tuple{PkgId, String}}}(), + Dict{Tuple{PkgId, Union{String, Nothing}}, Union{Tuple{String, String}, Nothing}}() +) struct TOMLCache{Dates} diff --git a/base/precompilation.jl b/base/precompilation.jl index f43fee770c94a..3c6c6fa996f06 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -1258,6 +1258,11 @@ function _color_string(cstr::String, col::Union{Int64, Symbol}, hascolor) end # Can be merged with `maybe_cachefile_lock` in loading? +# Wraps the precompilation function `f` with cachefile lock handling. +# Returns the result from `f()`, which can be: +# - `nothing`: cache already existed +# - `Tuple{String, Union{Nothing, String}}`: this process just compiled +# - `Exception`: compilation failed function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor, parallel_limiter::Base.Semaphore) if !(isdefined(Base, :mkpidlock_hook) && isdefined(Base, :trymkpidlock_hook) && Base.isdefined(Base, :parse_pidfile_hook)) return f() @@ -1284,7 +1289,7 @@ function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLo Base.release(parallel_limiter) # release so other work can be done while waiting try # wait until the lock is available - @invokelatest Base.mkpidlock_hook(() -> begin + cachefile = @invokelatest Base.mkpidlock_hook(() -> begin delete!(pkgspidlocked, pkg_config) Base.acquire(f, parallel_limiter) end, diff --git a/base/shell.jl b/base/shell.jl index 09b91918f2634..78b1af5645d2e 100644 --- a/base/shell.jl +++ b/base/shell.jl @@ -171,7 +171,7 @@ function shell_split(s::AbstractString) parsed = shell_parse(s, false)[1] args = String[] for arg in parsed - push!(args, string(arg...)) + push!(args, string(arg...)::String) end args end diff --git a/base/strings/annotated.jl b/base/strings/annotated.jl index 89cba6db42c8d..6bc0c76fdbaa8 100644 --- a/base/strings/annotated.jl +++ b/base/strings/annotated.jl @@ -250,7 +250,7 @@ function annotatedstring(xs...) size = filesize(s.io) if x isa AnnotatedString for annot in x.annotations - push!(annotations, setindex(annot, annot.region .+ size, :region)) + push!(annotations, @inline(setindex(annot, annot.region .+ size, :region))) end print(s, x.string) elseif x isa SubString{<:AnnotatedString} @@ -259,7 +259,7 @@ function annotatedstring(xs...) if start <= x.offset + x.ncodeunits && stop > x.offset rstart = size + max(0, start - x.offset - 1) + 1 rstop = size + min(stop, x.offset + x.ncodeunits) - x.offset - push!(annotations, setindex(annot, rstart:rstop, :region)) + push!(annotations, @inline(setindex(annot, rstart:rstop, :region))) end end print(s, SubString(x.string.string, x.offset, x.ncodeunits, Val(:noshift))) @@ -293,12 +293,12 @@ function repeat(str::AnnotatedString, r::Integer) elseif allequal(a -> a.region, str.annotations) && first(str.annotations).region == fullregion newfullregion = firstindex(unannot):lastindex(unannot) for annot in str.annotations - push!(annotations, setindex(annot, newfullregion, :region)) + push!(annotations, @inline(setindex(annot, newfullregion, :region))) end else for offset in 0:len:(r-1)*len for annot in str.annotations - push!(annotations, setindex(annot, annot.region .+ offset, :region)) + push!(annotations, @inline(setindex(annot, annot.region .+ offset, :region))) end end end @@ -318,10 +318,10 @@ function reverse(s::AnnotatedString) lastind = lastindex(s) AnnotatedString( reverse(s.string), - [setindex(annot, + [@inline(setindex(annot, UnitRange(1 + lastind - last(annot.region), 1 + lastind - first(annot.region)), - :region) + :region)) for annot in s.annotations]) end @@ -389,16 +389,28 @@ See also: [`annotate!`](@ref). annotations(s::AnnotatedString) = s.annotations function annotations(s::SubString{<:AnnotatedString}) - RegionAnnotation[ - setindex(ann, first(ann.region)-s.offset:last(ann.region)-s.offset, :region) - for ann in annotations(s.string, s.offset+1:s.offset+s.ncodeunits)] + substr_range = s.offset+1:s.offset+s.ncodeunits + result = RegionAnnotation[] + for ann in annotations(s.string, substr_range) + # Shift the region to be relative to the substring start + shifted_region = first(ann.region)-s.offset:last(ann.region)-s.offset + # @inline setindex makes :region const knowable (#60365) + push!(result, @inline(setindex(ann, shifted_region, :region))) + end + return result end function annotations(s::AnnotatedString, pos::UnitRange{<:Integer}) # TODO optimise - RegionAnnotation[ - setindex(ann, max(first(pos), first(ann.region)):min(last(pos), last(ann.region)), :region) - for ann in s.annotations if !isempty(intersect(pos, ann.region))] + result = RegionAnnotation[] + for ann in s.annotations + if !isempty(intersect(pos, ann.region)) + clamped_region = max(first(pos), first(ann.region)):min(last(pos), last(ann.region)) + # @inline setindex makes :region const knowable (#60365) + push!(result, @inline(setindex(ann, clamped_region, :region))) + end + end + return result end annotations(s::AnnotatedString, pos::Integer) = annotations(s, pos:pos) @@ -455,7 +467,7 @@ function annotated_chartransform(f::Function, str::AnnotatedString, state=nothin start, stop = first(annot.region), last(annot.region) start_offset = last(offsets[findlast(<=(start) ∘ first, offsets)::Int]) stop_offset = last(offsets[findlast(<=(stop) ∘ first, offsets)::Int]) - push!(annots, setindex(annot, (start + start_offset):(stop + stop_offset), :region)) + push!(annots, @inline(setindex(annot, (start + start_offset):(stop + stop_offset), :region))) end AnnotatedString(takestring!(outstr), annots) end @@ -509,7 +521,7 @@ function eachregion(s::AnnotatedString, subregion::UnitRange{Int}=firstindex(s): pos = first(events).pos if pos > first(subregion) push!(regions, thisind(s, first(subregion)):prevind(s, pos)) - push!(annots, []) + push!(annots, Annotation[]) end activelist = Int[] for event in events @@ -526,7 +538,7 @@ function eachregion(s::AnnotatedString, subregion::UnitRange{Int}=firstindex(s): end if last(events).pos < nextind(s, last(subregion)) push!(regions, last(events).pos:thisind(s, last(subregion))) - push!(annots, []) + push!(annots, Annotation[]) end RegionIterator(s.string, regions, annots) end diff --git a/base/strings/annotated_io.jl b/base/strings/annotated_io.jl index 60c91be24ebfb..519c6ebb7799d 100644 --- a/base/strings/annotated_io.jl +++ b/base/strings/annotated_io.jl @@ -52,7 +52,7 @@ function write(dest::AnnotatedIOBuffer, src::AnnotatedIOBuffer) srcpos = position(src) nb = write(dest.io, src.io) isappending || _clear_annotations_in_region!(dest.annotations, destpos:destpos+nb) - srcannots = [setindex(annot, max(1 + srcpos, first(annot.region)):last(annot.region), :region) + srcannots = [@inline(setindex(annot, max(1 + srcpos, first(annot.region)):last(annot.region), :region)) for annot in src.annotations if first(annot.region) >= srcpos] _insert_annotations!(dest, srcannots, destpos - srcpos) nb @@ -78,10 +78,11 @@ function write(io::AbstractPipe, c::AnnotatedChar) end function read(io::AnnotatedIOBuffer, ::Type{AnnotatedString{T}}) where {T <: AbstractString} - if (start = position(io)) == 0 + start = position(io) + if start == 0 AnnotatedString(read(io.io, T), copy(io.annotations)) else - annots = [setindex(annot, UnitRange{Int}(max(1, first(annot.region) - start), last(annot.region)-start), :region) + annots = [@inline(setindex(annot, UnitRange{Int}(max(1, first(annot.region) - start), last(annot.region)-start), :region)) for annot in io.annotations if last(annot.region) > start] AnnotatedString(read(io.io, T), annots) end @@ -101,7 +102,7 @@ read(io::AnnotatedIOBuffer, ::Type{AnnotatedChar}) = read(io, AnnotatedChar{Char function truncate(io::AnnotatedIOBuffer, size::Integer) truncate(io.io, size) filter!(ann -> first(ann.region) <= size, io.annotations) - map!(ann -> setindex(ann, first(ann.region):min(size, last(ann.region)), :region), + map!(ann -> @inline(setindex(ann, first(ann.region):min(size, last(ann.region)), :region)), io.annotations, io.annotations) io end @@ -125,17 +126,17 @@ function _clear_annotations_in_region!(annotations::Vector{RegionAnnotation}, sp # Test for partial overlap if first(region) <= first(span) <= last(region) || first(region) <= last(span) <= last(region) annotations[i] = - setindex(annot, + @inline(setindex(annot, if first(region) < first(span) first(region):first(span)-1 else last(span)+1:last(region) end, - :region) + :region)) # If `span` fits exactly within `region`, then we've only copied over # the beginning overhang, but also need to conserve the end overhang. if first(region) < first(span) && last(span) < last(region) - push!(extras, (i, setindex(annot, last(span)+1:last(region), :region))) + push!(extras, (i, @inline(setindex(annot, last(span)+1:last(region), :region)))) end end end diff --git a/base/terminfo.jl b/base/terminfo.jl index be0dd53b1ac74..fec0ed800cddf 100644 --- a/base/terminfo.jl +++ b/base/terminfo.jl @@ -69,7 +69,7 @@ struct TermInfo aliases::Dict{Symbol, Symbol} end -TermInfo() = TermInfo([], Dict(), Dict(), Dict(), nothing, Dict()) +TermInfo() = TermInfo(String[], Dict{Symbol, Bool}(), Dict{Symbol, Int}(), Dict{Symbol, String}(), nothing, Dict{Symbol, Symbol}()) function read(data::IO, ::Type{TermInfoRaw}) # Parse according to `term(5)` diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index 94f480c65dcf7..27d3da95a7811 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ -JULIASYNTAX_BRANCH = main -JULIASYNTAX_SHA1 = 99e975a726a82994de3f8e961e6fa8d39aed0d37 +JULIASYNTAX_BRANCH = release-1.13 +JULIASYNTAX_SHA1 = c02bc7a9151f36e46daea509827545d44132df2e JULIASYNTAX_GIT_URL := https://github.com/JuliaLang/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/JuliaLang/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-99e975a726a82994de3f8e961e6fa8d39aed0d37.tar.gz/md5 b/deps/checksums/JuliaSyntax-99e975a726a82994de3f8e961e6fa8d39aed0d37.tar.gz/md5 deleted file mode 100644 index 12fce1e97c1db..0000000000000 --- a/deps/checksums/JuliaSyntax-99e975a726a82994de3f8e961e6fa8d39aed0d37.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -ecef4caa8b237a51f92d5622b811a0c3 diff --git a/deps/checksums/JuliaSyntax-99e975a726a82994de3f8e961e6fa8d39aed0d37.tar.gz/sha512 b/deps/checksums/JuliaSyntax-99e975a726a82994de3f8e961e6fa8d39aed0d37.tar.gz/sha512 deleted file mode 100644 index f042854e27a47..0000000000000 --- a/deps/checksums/JuliaSyntax-99e975a726a82994de3f8e961e6fa8d39aed0d37.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -56dc5158ebfaf0d5e3e5002dfeb322a137f0866add071cfa9f7a0d9ef2d40859e4c6131358c5aeaf0e9e39fe77a94ba88022028092230b059099cd87e2b795ac diff --git a/deps/checksums/JuliaSyntax-c02bc7a9151f36e46daea509827545d44132df2e.tar.gz/md5 b/deps/checksums/JuliaSyntax-c02bc7a9151f36e46daea509827545d44132df2e.tar.gz/md5 new file mode 100644 index 0000000000000..9b6db0a270505 --- /dev/null +++ b/deps/checksums/JuliaSyntax-c02bc7a9151f36e46daea509827545d44132df2e.tar.gz/md5 @@ -0,0 +1 @@ +8fccef621fc59fd982a64d2a570f4e2d diff --git a/deps/checksums/JuliaSyntax-c02bc7a9151f36e46daea509827545d44132df2e.tar.gz/sha512 b/deps/checksums/JuliaSyntax-c02bc7a9151f36e46daea509827545d44132df2e.tar.gz/sha512 new file mode 100644 index 0000000000000..1e31e491453ff --- /dev/null +++ b/deps/checksums/JuliaSyntax-c02bc7a9151f36e46daea509827545d44132df2e.tar.gz/sha512 @@ -0,0 +1 @@ +8deefdfa0e2eaf1a269e90ad0e779a3fc9c2a4b7d87d0d70afd35857b22c8b1b9f91304b2b7ebc70595ab77bf1399a2dafb3ba7fd990515c5f87c4a4fe0a23dc diff --git a/deps/checksums/Pkg-4f9884fdb867f2c928ba43dc41da5f150aaec4ab.tar.gz/md5 b/deps/checksums/Pkg-4f9884fdb867f2c928ba43dc41da5f150aaec4ab.tar.gz/md5 deleted file mode 100644 index 45f5692993470..0000000000000 --- a/deps/checksums/Pkg-4f9884fdb867f2c928ba43dc41da5f150aaec4ab.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -cb635b45a66cab302b34bf56367e69d7 diff --git a/deps/checksums/Pkg-4f9884fdb867f2c928ba43dc41da5f150aaec4ab.tar.gz/sha512 b/deps/checksums/Pkg-4f9884fdb867f2c928ba43dc41da5f150aaec4ab.tar.gz/sha512 deleted file mode 100644 index c512a594e877d..0000000000000 --- a/deps/checksums/Pkg-4f9884fdb867f2c928ba43dc41da5f150aaec4ab.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -40a0495141d6b220bbc6b4119369cdc86b22498ca6a9c83eba47aec397c4c92afa5776e9043b1545a3111ace0317ca0c2412d0ba51731a7505742f47545a5530 diff --git a/deps/checksums/Pkg-e192350baaa01afb467c6ae8986e1babd9c673d1.tar.gz/md5 b/deps/checksums/Pkg-e192350baaa01afb467c6ae8986e1babd9c673d1.tar.gz/md5 new file mode 100644 index 0000000000000..571b8be8e742c --- /dev/null +++ b/deps/checksums/Pkg-e192350baaa01afb467c6ae8986e1babd9c673d1.tar.gz/md5 @@ -0,0 +1 @@ +1fa5749ed9d73b565fe689a5bd53476c diff --git a/deps/checksums/Pkg-e192350baaa01afb467c6ae8986e1babd9c673d1.tar.gz/sha512 b/deps/checksums/Pkg-e192350baaa01afb467c6ae8986e1babd9c673d1.tar.gz/sha512 new file mode 100644 index 0000000000000..548a0108ee113 --- /dev/null +++ b/deps/checksums/Pkg-e192350baaa01afb467c6ae8986e1babd9c673d1.tar.gz/sha512 @@ -0,0 +1 @@ +de0d6283143a8bc20c122b4960371a15e8c24f222252b1e6f2455aaefbcb659b6620e32de0897257935e28cb188e76443e4e715ba1c1731515a31e70c7dcd22a diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index c11357d276482..652982c6c7523 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -816,9 +816,12 @@ void *jl_emit_native_impl(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvm continue; // skip any duplicates that accidentally made there way in here (or make this an error?) if (jl_ir_inlining_cost((jl_value_t*)src) < UINT16_MAX) params.safepoint_on_entry = false; // ensure we don't block ExpandAtomicModifyPass from inlining this code if applicable - orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), - params.tsctx, clone.getModuleUnlocked()->getDataLayout(), - Triple(clone.getModuleUnlocked()->getTargetTriple())); + orc::ThreadSafeModule result_m = + jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), + params.tsctx, + clone.getModuleUnlocked()->getDataLayout(), + Triple(clone.getModuleUnlocked()->getTargetTriple()), + clone.getModuleUnlocked()); jl_llvm_functions_t decls; if (!(params.params->force_emit_all) && jl_atomic_load_relaxed(&codeinst->invoke) == jl_fptr_const_return_addr) decls.functionObject = "jl_fptr_const_return"; diff --git a/src/codegen.cpp b/src/codegen.cpp index 9dcf1264581c0..a595fbc1fdcc6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2276,6 +2276,19 @@ static inline jl_cgval_t value_to_pointer(jl_codectx_t &ctx, const jl_cgval_t &v Align align(julia_alignment(v.typ)); Type *ty = julia_type_to_llvm(ctx, v.typ); AllocaInst *loc = emit_static_alloca(ctx, ty, align); + jl_datatype_t *dt = (jl_datatype_t *)v.typ; + size_t npointers = dt->layout->first_ptr >= 0 ? dt->layout->npointers : 0; + if (npointers > 0) { + auto InsertPoint = ctx.builder.saveIP(); + ctx.builder.SetInsertPoint(ctx.topalloca->getParent(), ++ctx.topalloca->getIterator()); + for (size_t i = 0; i < npointers; i++) { + // make sure these are nullptr early from LLVM's perspective, in case it decides to SROA it + Value *ptr_field = emit_ptrgep(ctx, loc, jl_ptr_offset(dt, i) * sizeof(void *)); + ctx.builder.CreateAlignedStore( + Constant::getNullValue(ctx.types().T_prjlvalue), ptr_field, Align(sizeof(void *))); + } + ctx.builder.restoreIP(InsertPoint); + } auto tbaa = v.V == nullptr ? ctx.tbaa().tbaa_gcframe : ctx.tbaa().tbaa_stack; auto stack_ai = jl_aliasinfo_t::fromTBAA(ctx, tbaa); recombine_value(ctx, v, loc, stack_ai, align, false); @@ -2671,17 +2684,12 @@ static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_ return jl_cgval_t(v, typ, new_tindex); } -std::unique_ptr jl_create_llvm_module(StringRef name, LLVMContext &context, const DataLayout &DL, const Triple &triple) JL_NOTSAFEPOINT +std::unique_ptr jl_create_llvm_module(StringRef name, LLVMContext &context, + const DataLayout &DL, const Triple &triple, + Module *source) JL_NOTSAFEPOINT { ++ModulesCreated; auto m = std::make_unique(name, context); - // According to clang darwin above 10.10 supports dwarfv4 - if (!m->getModuleFlag("Dwarf Version")) { - m->addModuleFlag(llvm::Module::Warning, "Dwarf Version", 4); - } - if (!m->getModuleFlag("Debug Info Version")) - m->addModuleFlag(llvm::Module::Warning, "Debug Info Version", - llvm::DEBUG_METADATA_VERSION); m->setDataLayout(DL); m->setTargetTriple(triple.str()); @@ -2692,9 +2700,29 @@ std::unique_ptr jl_create_llvm_module(StringRef name, LLVMContext &conte m->setOverrideStackAlignment(16); } + if (source) { + // Copy module flags from source module + SmallVector Flags; + source->getModuleFlagsMetadata(Flags); + for (const auto &Flag : Flags) { + m->addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val); + } + // Copy other module-level properties + m->setStackProtectorGuard(source->getStackProtectorGuard()); + m->setOverrideStackAlignment(source->getOverrideStackAlignment()); + } + else { + // No source: set default Julia flags + // According to clang darwin above 10.10 supports dwarfv4 + m->addModuleFlag(llvm::Module::Warning, "Dwarf Version", 4); + m->addModuleFlag(llvm::Module::Warning, "Debug Info Version", + llvm::DEBUG_METADATA_VERSION); + #if defined(JL_DEBUG_BUILD) - m->setStackProtectorGuard("global"); + m->setStackProtectorGuard("global"); #endif + } + return m; } diff --git a/src/jitlayers.h b/src/jitlayers.h index 331d9accc8fb8..f77b21ce39d21 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -667,10 +667,16 @@ class JuliaOJIT { OptSelLayerT OptSelLayer; }; extern JuliaOJIT *jl_ExecutionEngine; -std::unique_ptr jl_create_llvm_module(StringRef name, LLVMContext &ctx, const DataLayout &DL, const Triple &triple) JL_NOTSAFEPOINT; -inline orc::ThreadSafeModule jl_create_ts_module(StringRef name, orc::ThreadSafeContext ctx, const DataLayout &DL, const Triple &triple) JL_NOTSAFEPOINT { +std::unique_ptr jl_create_llvm_module(StringRef name, LLVMContext &ctx, + const DataLayout &DL, const Triple &triple, + Module *source = nullptr) JL_NOTSAFEPOINT; +inline orc::ThreadSafeModule jl_create_ts_module(StringRef name, orc::ThreadSafeContext ctx, + const DataLayout &DL, const Triple &triple, + Module *source = nullptr) JL_NOTSAFEPOINT +{ auto lock = ctx.getLock(); - return orc::ThreadSafeModule(jl_create_llvm_module(name, *ctx.getContext(), DL, triple), ctx); + return orc::ThreadSafeModule( + jl_create_llvm_module(name, *ctx.getContext(), DL, triple, source), ctx); } Module &jl_codegen_params_t::shared_module() JL_NOTSAFEPOINT { diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index f3a57c6699c08..c9b1fd551e359 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -1809,11 +1809,13 @@ (cons e '()) (let ((a '())) (define (arg-to-temp x) - (cond ((effect-free? x) x) - ((or (eq? (car x) '...) (eq? (car x) '&)) - `(,(car x) ,(arg-to-temp (cadr x)))) + (cond ((effect-free? x) x) + ((eq? (car x) '...) + `(... ,(arg-to-temp (cadr x)))) ((eq? (car x) 'kw) - `(,(car x) ,(cadr x) ,(arg-to-temp (caddr x)))) + `(kw ,(cadr x) ,(arg-to-temp (caddr x)))) + ((eq? (car x) 'parameters) + `(parameters ,@(map arg-to-temp (cdr x)))) (else (let ((g (make-ssavalue))) (begin (set! a (cons `(= ,g ,x) a)) diff --git a/src/support/dtypes.h b/src/support/dtypes.h index 2ee2d3529c10d..44db067019cd9 100644 --- a/src/support/dtypes.h +++ b/src/support/dtypes.h @@ -27,7 +27,9 @@ #define WIN32_LEAN_AND_MEAN /* Clang does not like fvisibility=hidden with windows headers. This adds the visibility attribute there. Arguably this is a clang bug. */ -#define DECLSPEC_IMPORT __declspec(dllimport) __attribute__ ((visibility("default"))) +# ifndef _COMPILER_MICROSOFT_ +# define DECLSPEC_IMPORT __declspec(dllimport) __attribute__ ((visibility("default"))) +# endif #include #if defined(_COMPILER_MICROSOFT_) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) @@ -59,15 +61,21 @@ typedef intptr_t ssize_t; */ #ifdef _OS_WINDOWS_ +# ifndef _COMPILER_MICROSOFT_ +# define JL_VISIBILITY_DEFAULT __attribute__ ((visibility("default"))) +# else +# define JL_VISIBILITY_DEFAULT +# define JL_VISIBILITY_HIDDEN +# endif #define STDCALL __stdcall # ifdef JL_LIBRARY_EXPORTS_INTERNAL -# define JL_DLLEXPORT __declspec(dllexport) __attribute__ ((visibility("default"))) +# define JL_DLLEXPORT __declspec(dllexport) JL_VISIBILITY_DEFAULT # endif # ifdef JL_LIBRARY_EXPORTS_CODEGEN -# define JL_DLLEXPORT_CODEGEN __declspec(dllexport) __attribute__ ((visibility("default"))) +# define JL_DLLEXPORT_CODEGEN __declspec(dllexport) JL_VISIBILITY_DEFAULT # endif #define JL_HIDDEN -#define JL_DLLIMPORT __declspec(dllimport) __attribute__ ((visibility("default"))) +#define JL_DLLIMPORT __declspec(dllimport) JL_VISIBILITY_DEFAULT #else #define STDCALL #define JL_DLLIMPORT __attribute__ ((visibility("default"))) diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 2970f3583bdf3..91d47d14397d1 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = release-1.13 -PKG_SHA1 = 4f9884fdb867f2c928ba43dc41da5f150aaec4ab +PKG_SHA1 = e192350baaa01afb467c6ae8986e1babd9c673d1 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 diff --git a/stdlib/REPL/src/History/resumablefiltering.jl b/stdlib/REPL/src/History/resumablefiltering.jl index 21c1239a60388..8d1f377266a2e 100644 --- a/stdlib/REPL/src/History/resumablefiltering.jl +++ b/stdlib/REPL/src/History/resumablefiltering.jl @@ -24,7 +24,7 @@ const FILTER_SEPARATOR = ';' List of single-character prefixes that set search modes. """ -const FILTER_PREFIXES = ('!', '`', '=', '/', '~', '>') +const FILTER_PREFIXES = ('!', '`', '=', '/', '~') """ FILTER_SHORTHELP_QUERY @@ -53,20 +53,22 @@ const FILTER_SHORTHELP = S""" See more information on behaviour and keybindings with '{REPL_History_search_prefix:??}'. + By default, each word in the search string is looked for in any order. + Should the search string start with {REPL_History_search_prefix:xyz>}, then only xyz-mode entries are considered. + Different search modes are available via prefixes, as follows: {emphasis:•} {REPL_History_search_prefix:=} looks for exact matches {emphasis:•} {REPL_History_search_prefix:!} {italic:excludes} exact matches {emphasis:•} {REPL_History_search_prefix:/} performs a regexp search {emphasis:•} {REPL_History_search_prefix:~} looks for fuzzy matches - {emphasis:•} {REPL_History_search_prefix:>} looks for a particular REPL mode {emphasis:•} {REPL_History_search_prefix:`} looks for an initialism (text with matching initials) You can also apply multiple restrictions with the separator '{REPL_History_search_separator:$FILTER_SEPARATOR}'. For example, {region:{REPL_History_search_prefix:/}^foo{REPL_History_search_separator:$FILTER_SEPARATOR}\ {REPL_History_search_prefix:`}bar{REPL_History_search_separator:$FILTER_SEPARATOR}\ -{REPL_History_search_prefix:>}shell} will look for history entries that start with "{code:foo}", - contains "{code:b... a... r...}", {italic:and} is a shell history entry. +{REPL_History_search_prefix:shell>}} will look for history entries that start with "{code:foo}", + contains "{code:b... a... r...}", {italic:and} are a shell history entry. """ const FILTER_LONGHELP = S""" @@ -108,9 +110,9 @@ function ConditionSet(spec::S) where {S <: AbstractString} function addcond!(condset::ConditionSet, cond::SubString) isempty(cond) && return kind = first(cond) - if kind ∈ ('!', '=', '`', '/', '>', '~') + if kind ∈ ('!', '=', '`', '/', '~') value = @view cond[2:end] - if kind ∈ ('`', '>', '~') + if kind ∈ ('`', '~') value = strip(value) elseif !all(isspace, value) value = if kind == '/' @@ -128,16 +130,23 @@ function ConditionSet(spec::S) where {S <: AbstractString} push!(condset.initialisms, value) elseif startswith(cond, '/') push!(condset.regexps, value) - elseif startswith(cond, '>') - push!(condset.modes, SubString(lowercase(value))) elseif startswith(cond, '~') push!(condset.fuzzy, value) end else if startswith(cond, '\\') && !(length(cond) > 1 && cond[2] == '\\') cond = @view cond[2:end] + else + rang = something(findfirst('>', cond), typemax(Int)) + if rang == something(findfirst(isspace, cond), ncodeunits(cond) + 1) - 1 + mode = @view cond[1:prevind(cond, rang)] + push!(condset.modes, SubString(lowercase(mode))) + cond = @view cond[rang + 1:end] + end end - push!(condset.words, strip(cond)) + cond = strip(cond) + isempty(cond) && return + push!(condset.words, cond) end nothing end @@ -155,10 +164,12 @@ function ConditionSet(spec::S) where {S <: AbstractString} elseif chr == '\\' escaped = true elseif chr == FILTER_SEPARATOR - str = SubString(spec, mark:pos - 1) - if !isempty(dropbytes) - str = SubString(convert(S, String(deleteat!(collect(codeunits(str)), dropbytes)))) + str = if isempty(dropbytes) + SubString(spec, mark:prevind(spec, pos)) + else + subbytes = deleteat!(codeunits(spec)[mark:pos-1], dropbytes) empty!(dropbytes) + SubString(convert(S, String(subbytes))) end addcond!(cset, lstrip(str)) mark = pos + 1 @@ -166,11 +177,14 @@ function ConditionSet(spec::S) where {S <: AbstractString} pos = nextind(spec, pos) end if mark <= lastind - str = SubString(spec, mark:pos - 1) - if !isempty(dropbytes) - str = SubString(convert(S, String(deleteat!(collect(codeunits(str)), dropbytes)))) + str = if isempty(dropbytes) + SubString(spec, mark) + else + subbytes = deleteat!(codeunits(spec)[mark:end], dropbytes) + empty!(dropbytes) + SubString(convert(S, String(subbytes))) end - addcond!(cset, lstrip(SubString(spec, mark:lastind))) + addcond!(cset, lstrip(str)) end cset end diff --git a/stdlib/REPL/test/history.jl b/stdlib/REPL/test/history.jl index 59abbebb8326c..8c130cd0c0ee6 100644 --- a/stdlib/REPL/test/history.jl +++ b/stdlib/REPL/test/history.jl @@ -206,7 +206,7 @@ end @test cset.regexps == [SubString("foo.*bar")] end @testset "Mode" begin - cset = ConditionSet(">shell") + cset = ConditionSet("shell>") @test cset.modes == [SubString("shell")] end @testset "Fuzzy" begin @@ -231,9 +231,11 @@ end cset = ConditionSet("hello\\;world;=exact") @test cset.words == [SubString("hello;world")] @test cset.exacts == [SubString("exact")] + cset = ConditionSet("1 \\; 2") + @test cset.words == [SubString("1 ; 2")] end @testset "Complex query" begin - cset = ConditionSet("some = words ;; !error ;> julia;/^def.*;") + cset = ConditionSet("some = words ;; !error ; julia> ;/^def.*;") @test cset.words == [SubString("some = words")] @test cset.negatives == [SubString("error")] @test cset.modes == [SubString("julia")] @@ -254,7 +256,7 @@ end @test isempty(spec2.regexps) end @testset "Complex query" begin - cset = ConditionSet("=exact;!neg;/foo.*bar;>julia") + cset = ConditionSet("=exact;!neg;/foo.*bar;julia>") spec = FilterSpec(cset) @test spec.exacts == ["exact"] @test spec.negatives == ["neg"] @@ -341,7 +343,7 @@ end end @testset "Mode" begin empty!(results) - cset = ConditionSet(">shell") + cset = ConditionSet("shell>") spec = FilterSpec(cset) seen = Set{Tuple{Symbol,String}}() @test filterchunkrev!(results, entries, spec, seen) == 0 diff --git a/test/syntax.jl b/test/syntax.jl index cec389be057ad..eef4e58bb626d 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -3730,7 +3730,7 @@ end @test p("public() = 6") == Expr(:(=), Expr(:call, :public), Expr(:block, 6)) end -@testset "removing argument sideeffects" begin +@testset "removing argument side effects" begin # Allow let blocks in broadcasted LHSes, but only evaluate them once: execs = 0 array = [1] @@ -3746,6 +3746,15 @@ end let; execs += 1; array; end::Vector{Int} .= 7 @test array == [7] @test execs == 4 + + # remove argument side effects on lhs kwcall + pa_execs = 0 + kw_execs = 0 + f60152(v, pa; kw) = copy(v) + @test (f60152([1, 2, 3], 0; kw=0) .*= 2) == [2,4,6] + @test (f60152([1, 2, 3], (pa_execs+=1); kw=(kw_execs+=1)) .*= 2) == [2,4,6] + @test pa_execs === 1 + @test kw_execs === 1 end # Allow GlobalRefs in macro definition