Skip to content

Commit d4e80a0

Browse files
committed
fix #57749, model ccall binding access in inference
1 parent 056e68b commit d4e80a0

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

Compiler/src/abstractinterpretation.jl

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3485,7 +3485,57 @@ function refine_partial_type(@nospecialize t)
34853485
return t
34863486
end
34873487

3488+
function abstract_eval_nonlinearized_foreigncall_name(interp::AbstractInterpreter, e, sstate::StatementState, sv::AbsIntState)
3489+
if isexpr(e, :call)
3490+
n = length(e.args)
3491+
argtypes = Vector{Any}(undef, n)
3492+
callresult = Future{CallMeta}()
3493+
i::Int = 1
3494+
nextstate::UInt8 = 0x0
3495+
local ai, res
3496+
function evalargs(interp, sv)
3497+
if nextstate === 0x1
3498+
@goto state1
3499+
elseif nextstate === 0x2
3500+
@goto state2
3501+
end
3502+
while i <= n
3503+
ai = abstract_eval_nonlinearized_foreigncall_name(interp, e.args[i], sstate, sv)
3504+
if !isready(ai)
3505+
nextstate = 0x1
3506+
return false
3507+
@label state1
3508+
end
3509+
argtypes[i] = ai[].rt
3510+
i += 1
3511+
end
3512+
res = abstract_call(interp, ArgInfo(e.args, argtypes), sstate, sv)
3513+
if !isready(res)
3514+
nextstate = 0x2
3515+
return false
3516+
@label state2
3517+
end
3518+
callresult[] = res[]
3519+
return true
3520+
end
3521+
evalargs(interp, sv) || push!(sv.tasks, evalargs)
3522+
return callresult
3523+
else
3524+
return Future(abstract_eval_basic_statement(interp, e, sstate, sv))
3525+
end
3526+
end
3527+
34883528
function abstract_eval_foreigncall(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState)
3529+
callee = e.args[1]
3530+
if isexpr(callee, :call) && length(callee.args) > 1 && callee.args[1] == GlobalRef(Core, :tuple)
3531+
# NOTE these expressions are not properly linearized
3532+
abstract_eval_nonlinearized_foreigncall_name(interp, callee.args[2], sstate, sv)
3533+
if length(callee.args) > 2
3534+
abstract_eval_nonlinearized_foreigncall_name(interp, callee.args[3], sstate, sv)
3535+
end
3536+
else
3537+
abstract_eval_value(interp, callee, sstate, sv)
3538+
end
34893539
mi = frame_instance(sv)
34903540
t = sp_type_rewrap(e.args[2], mi, true)
34913541
for i = 3:length(e.args)

test/ccall.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,3 +1979,11 @@ let llvm = sprint(code_llvm, gc_safe_ccall, ())
19791979
# check for the gc_safe store
19801980
@test occursin("store atomic i8 2", llvm)
19811981
end
1982+
1983+
module Test57749
1984+
using Test, Zstd_jll
1985+
const prefix = "Zstd version: "
1986+
const sym = :ZSTD_versionString
1987+
get_zstd_version() = prefix * unsafe_string(ccall((sym, libzstd), Cstring, ()))
1988+
@test startswith(get_zstd_version(), "Zstd")
1989+
end

0 commit comments

Comments
 (0)