Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix LLVM IR verification error found via PonyCheck #4039

Merged
merged 1 commit into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .release-notes/fix_llvm_call_receiver_type_cast.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Fix call receiver type casting in LLVM IR

In some rare cases (such as in the PonyCheck library), `ponyc` was generating LLVM that did not use the correct pointer types for call site receiver arguments. This did not result in unsafe code at runtime, but it was still a violation of the LLVM type system, and it caused the "Verification" step of compilation to fail when enabled.

To fix this issue, we introduced an LLVM bitcast at such call sites to cast the receiver pointer to the correct LLVM type.
13 changes: 13 additions & 0 deletions src/libponyc/codegen/gencall.c
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,19 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast)
LLVMTypeRef* params = (LLVMTypeRef*)ponyint_pool_alloc_size(buf_size);
LLVMGetParamTypes(f_type, params + (bare ? 1 : 0));

// For non-bare functions, ensure that we cast the receiver arg type
// to match the param type of the function.
if(!bare)
{
LLVMTypeRef func_receiver_type = params[0];
LLVMTypeRef call_receiver_type = LLVMTypeOf(args[0]);

if (func_receiver_type != call_receiver_type)
args[0] = LLVMBuildBitCast(c->builder, args[0], func_receiver_type, "");
}

// We also need to cast the rest of the arguments, using the same casting
// semantics as assignment.
arg = ast_child(positional);
i = 1;

Expand Down