Skip to content

Commit

Permalink
Null-check function pointer invocation #1573.
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Oct 26, 2024
1 parent b187d5a commit cc6a24c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Defer resolution of declarations when looked up in `def` aliased #1559.
- Adding constants to the Json AST #1540
- Adding info to the globals inside Json AST #1541
- Null-check function pointer invocation #1573.

### Fixes
- `Unsupported int[*] $x = { 1, 2, 3, 4 }` #1489.
Expand Down
10 changes: 10 additions & 0 deletions src/compiler/llvm_codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -6206,6 +6206,16 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr
// 1d. Load it as a value
func = llvm_load_value_store(c, &func_value);

if (safe_mode_enabled())
{
LLVMValueRef check = LLVMBuildICmp(c->builder, LLVMIntEQ, func, LLVMConstNull(c->ptr_type), "checknull");
scratch_buffer_clear();
scratch_buffer_append("Calling null function pointer, '");
span_to_scratch(function->span);
scratch_buffer_append("' was null.");
llvm_emit_panic_on_true(c, check, scratch_buffer_to_string(), function->span, NULL, NULL, NULL);
}

// 1e. Calculate the function type
func_type = llvm_get_type(c, type);
}
Expand Down
43 changes: 43 additions & 0 deletions test/test_suite/functions/func_ptr_null.check.c3t
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// #target: macos-aarch64
// #safe: yes
module test;
def TestFn = fn void();

fn int main()
{
TestFn foo;
foo();
return 0;
}

/* #expect: test.ll


define i32 @main() #0 {
entry:
%foo = alloca ptr, align 8
%taddr = alloca %"char[]", align 8
%taddr1 = alloca %"char[]", align 8
%taddr2 = alloca %"char[]", align 8
store ptr null, ptr %foo, align 8
%0 = load ptr, ptr %foo, align 8
%checknull = icmp eq ptr %0, null
%1 = call i1 @llvm.expect.i1(i1 %checknull, i1 false)
br i1 %1, label %panic, label %checkok

checkok: ; preds = %entry
call void %0()
ret i32 0

panic: ; preds = %entry
store %"char[]" { ptr @.panic_msg, i64 46 }, ptr %taddr, align 8
%2 = load [2 x i64], ptr %taddr, align 8
store %"char[]" { ptr @.file, i64 22 }, ptr %taddr1, align 8
%3 = load [2 x i64], ptr %taddr1, align 8
store %"char[]" { ptr @.func, i64 4 }, ptr %taddr2, align 8
%4 = load [2 x i64], ptr %taddr2, align 8
%5 = load ptr, ptr @std.core.builtin.panic, align 8
call void %5([2 x i64] %2, [2 x i64] %3, [2 x i64] %4, i32 7)
unreachable
}

0 comments on commit cc6a24c

Please sign in to comment.