Repository: JuliaDebug/Cthulhu.jl (julia)

Issue:
internal assertion error examining BigInt() constructor
```julia
julia> descend(BigInt, (), optimize=true, annotate_source=false)
BigInt(; nbits) @ Base.GMP gmp.jl:63
∘ ─ %0 = invoke BigInt()::BigInt
    @ gmp.jl:63 within `BigInt`
1 ─ %1 = invoke $(QuoteNode(Base.GMP.var"#_#1#2"()))(0::Int64, #ctor-self#::Type{BigInt})::BigInt
└──      return %1
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [w]arn, [h]ide type-stable statements, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native, [j]ump to source always, [o]ptimize, [d]ebuginfo, [r]emarks, [e]ffects, [i]nlining costs.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
Advanced: dump [P]arams cache.
 • %1 = < constprop > _#1(::Core.Const(0),::Core.Const(BigInt))::BigInt
   ↩
argextype called on Expr with head :call which is not valid for IR in argument-position.
ERROR: AssertionError: false
Stacktrace:
  [1] argextype(x::Any, src::Core.Compiler.IRCode, sptypes::Vector{Core.Compiler.VarState}, slottypes::Vector{Any})
    @ Core.Compiler ./compiler/optimize.jl:368
  [2] #11
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/reflection.jl:53 [inlined]
  [3] map!(f::Cthulhu.var"#11#12"{Core.Compiler.IRCode, Vector{Any}, Vector{Core.Compiler.VarState}}, dest::Vector{Any}, A::Vector{Any})
    @ Base ./abstractarray.jl:3300
  [4] mapany(f::Function, A::Vector{Any})
    @ Base ./abstractarray.jl:3309
  [5] find_callsites(interp::Cthulhu.CthulhuInterpreter, CI::Core.Compiler.IRCode, stmt_infos::Vector{Core.Compiler.CallInfo}, mi::Core.MethodInstance, slottypes::Vector{Any}, optimize::Bool, annotate_source::Bool)
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/reflection.jl:52
  [6] 
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/Cthulhu.jl:468
  [7] 
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/Cthulhu.jl:610
  [8] _descend(term::REPL.Terminals.TTYTerminal, interp::Cthulhu.CthulhuInterpreter, mi::Core.MethodInstance; kwargs::@Kwargs{iswarn::Bool, optimize::Bool, annotate_source::Bool})
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/Cthulhu.jl:756
  [9] _descend(term::REPL.Terminals.TTYTerminal, args::Any; interp::Core.Compiler.NativeInterpreter, kwargs::@Kwargs{iswarn::Bool, optimize::Bool, annotate_source::Bool})
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/Cthulhu.jl:772
 [10] __descend_with_error_handling(args::Any; terminal::Any, kwargs...)
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/Cthulhu.jl:213
 [11] _descend_with_error_handling(f::Any, argtypes::Any; kwargs::@Kwargs{iswarn::Bool, optimize::Bool, annotate_source::Bool})
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/Cthulhu.jl:202
 [12] descend_code_typed(::Any, ::Vararg{Any}; kwargs::@Kwargs{optimize::Bool, annotate_source::Bool})
    @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/Cthulhu.jl:160
 [13] top-level scope
    @ REPL[4]:1
Some type information was truncated. Use `show(err)` to see complete types.
```

Pull request:
fixes #515

Patch:
diff --git a/src/reflection.jl b/src/reflection.jl
index 1e5757f8..f69358fe 100644
--- a/src/reflection.jl
+++ b/src/reflection.jl
@@ -50,10 +50,16 @@ function find_callsites(interp::AbstractInterpreter, CI::Union{Core.CodeInfo, IR
                 if !optimize
                     args = (ignorelhs(stmt)::Expr).args
                 end
-                argtypes = mapany(function (@nospecialize(arg),)
-                                      t = argextype(arg, CI, sptypes, slottypes)
-                                      return ignorelimited(t)
-                                  end, args)
+                argtypes = Vector{Any}(undef, length(args))
+                ft = ignorelimited(argextype(args[1], CI, sptypes, slottypes))
+                f = CC.singleton_type(ft)
+                f === Core.Intrinsics.llvmcall && continue
+                f === Core.Intrinsics.cglobal && continue
+                argtypes[1] = ft
+                for i = 2:length(args)
+                    t = argextype(args[i], CI, sptypes, slottypes)
+                    argtypes[i] = ignorelimited(t)
+                end
                 exct = isnothing(pc2excts) ? nothing : get(pc2excts, id, nothing)
                 callinfos = process_info(interp, info, argtypes, rt, optimize, exct)
                 isempty(callinfos) && continue


Test patch:
diff --git a/test/test_Cthulhu.jl b/test/test_Cthulhu.jl
index 64dc7148..ebc66ee7 100644
--- a/test/test_Cthulhu.jl
+++ b/test/test_Cthulhu.jl
@@ -1016,4 +1016,12 @@ let (interp, mi) = Cthulhu.mkinterp((Int,)) do var::Int
     @test length(inferred.ir.cfg.blocks) == 1
 end
 
+f515() = cglobal((:foo, bar))
+@testset "issue #515" begin
+    let (; interp, src, infos, mi, slottypes) = cthulhu_info(f515)
+        callsites, _ = Cthulhu.find_callsites(interp, src, infos, mi, slottypes)
+        @test isempty(callsites)
+    end
+end
+
 end # module test_Cthulhu