Skip to content

Conversation

@achaljhawar
Copy link

Fixes the segmentation fault that occurred when passing zero-sized types to llvmcall. The compiler now validates argument and return types and throws a clear error message instead of crashing.

Before

julia> f(x::T) where T = Base.llvmcall("ret i8 %0", Int8, Tuple{T}, x); f(nothing)
[26746] signal 11 (1): Segmentation fault

After

julia> f(x::T) where T = Base.llvmcall("ret i8 %0", Int8, Tuple{T}, x); f(nothing)
ERROR: llvmcall does not support zero-sized argument types

Changes

  • Added validation in emit_llvmcall to detect zero-sized argument and return types
  • Added tests to verify proper error handling

fixes: #60063

@LilithHafner
Copy link
Member

Thanks! CI is failing with errors related to this PR, so maybe have a look at that. @vchuravy, would you be willing to give a closer review?

@vchuravy
Copy link
Member

I would defer to @vtjnash for the ABI part

@achaljhawar achaljhawar requested a review from vchuravy November 12, 2025 18:06
@achaljhawar achaljhawar force-pushed the fix-llvm-zero-args branch 2 times, most recently from 413e519 to b955f00 Compare November 12, 2025 18:53
bool retboxed;
Type *rettype = julia_type_to_llvm(ctx, rtt, &retboxed);
if (jl_is_datatype(rtt) && jl_datatype_size((jl_datatype_t*)rtt) == 0) {
emit_error(ctx, "llvmcall does not support zero-sized return types");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about void functions?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a check for that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The semantics here of checking if the user made an egregious typo are still wrong. This is also well formed:

julia> mutable struct A end

julia> f() = Core.Intrinsics.llvmcall("ret ptr addrspace(10) null", A, Tuple{})

This sort of random checking for user error doesn't really make sense to me. The point of llvmcall is an unsafe escape hatch into unsafe territory. If you don't like that, just don't use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

llvmcall segfaults if an argument has size 0

5 participants