Skip to content

Commit 41aa62e

Browse files
JeffBezansonKristofferC
authored andcommitted
model ccall binding access in inference (#58872)
fixes #57749 (cherry picked from commit b35c4f4)
1 parent c638304 commit 41aa62e

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
@@ -3444,7 +3444,59 @@ function refine_partial_type(@nospecialize t)
34443444
return t
34453445
end
34463446

3447+
abstract_eval_nonlinearized_foreigncall_name(interp::AbstractInterpreter, e, sstate::StatementState, sv::IRInterpretationState) = nothing
3448+
3449+
function abstract_eval_nonlinearized_foreigncall_name(interp::AbstractInterpreter, e, sstate::StatementState, sv::AbsIntState)
3450+
if isexpr(e, :call)
3451+
n = length(e.args)
3452+
argtypes = Vector{Any}(undef, n)
3453+
callresult = Future{CallMeta}()
3454+
i::Int = 1
3455+
nextstate::UInt8 = 0x0
3456+
local ai, res
3457+
function evalargs(interp, sv)
3458+
if nextstate === 0x1
3459+
@goto state1
3460+
elseif nextstate === 0x2
3461+
@goto state2
3462+
end
3463+
while i <= n
3464+
ai = abstract_eval_nonlinearized_foreigncall_name(interp, e.args[i], sstate, sv)
3465+
if !isready(ai)
3466+
nextstate = 0x1
3467+
return false
3468+
@label state1
3469+
end
3470+
argtypes[i] = ai[].rt
3471+
i += 1
3472+
end
3473+
res = abstract_call(interp, ArgInfo(e.args, argtypes), sstate, sv)
3474+
if !isready(res)
3475+
nextstate = 0x2
3476+
return false
3477+
@label state2
3478+
end
3479+
callresult[] = res[]
3480+
return true
3481+
end
3482+
evalargs(interp, sv) || push!(sv.tasks, evalargs)
3483+
return callresult
3484+
else
3485+
return Future(abstract_eval_basic_statement(interp, e, sstate, sv))
3486+
end
3487+
end
3488+
34473489
function abstract_eval_foreigncall(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState)
3490+
callee = e.args[1]
3491+
if isexpr(callee, :call) && length(callee.args) > 1 && callee.args[1] == GlobalRef(Core, :tuple)
3492+
# NOTE these expressions are not properly linearized
3493+
abstract_eval_nonlinearized_foreigncall_name(interp, callee.args[2], sstate, sv)
3494+
if length(callee.args) > 2
3495+
abstract_eval_nonlinearized_foreigncall_name(interp, callee.args[3], sstate, sv)
3496+
end
3497+
else
3498+
abstract_eval_value(interp, callee, sstate, sv)
3499+
end
34483500
mi = frame_instance(sv)
34493501
t = sp_type_rewrap(e.args[2], mi, true)
34503502
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)