Skip to content

Commit b35c4f4

Browse files
authored
model ccall binding access in inference (#58872)
fixes #57749
1 parent b58fd8b commit b35c4f4

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

Compiler/src/abstractinterpretation.jl

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

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