mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Distinct inline can now be called if it is aliasing a function pointer.
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
- Assertion with duplicate function pointer signatures #1286
|
||||
- Distinct func type would not accept direct function address assign. #1287
|
||||
- Distinct inline would not implement protocol if the inlined implemented it. #1292
|
||||
- Distinct inline can now be called if it is aliasing a function pointer.
|
||||
|
||||
### Stdlib changes
|
||||
|
||||
|
||||
@@ -6017,7 +6017,8 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr
|
||||
Expr *function = exprptr(expr->call_expr.function);
|
||||
|
||||
// 1a. Find the pointee type for the function pointer:
|
||||
Type *type = function->type->canonical->pointer;
|
||||
assert(type_flatten(function->type)->type_kind == TYPE_FUNC_PTR);
|
||||
Type *type = type_flatten(function->type)->pointer;
|
||||
|
||||
// 1b. Find the type signature using the underlying pointer.
|
||||
prototype = type_get_resolved_prototype(type);
|
||||
|
||||
@@ -1844,6 +1844,7 @@ static inline bool sema_call_analyse_func_invocation(SemaContext *context, Decl
|
||||
static inline bool sema_expr_analyse_var_call(SemaContext *context, Expr *expr, Type *func_ptr_type, bool optional, bool *no_match_ref)
|
||||
{
|
||||
Decl *decl = NULL;
|
||||
func_ptr_type = type_flat_distinct_inline(func_ptr_type);
|
||||
if (func_ptr_type->type_kind != TYPE_FUNC_PTR)
|
||||
{
|
||||
if (no_match_ref)
|
||||
@@ -1851,7 +1852,7 @@ static inline bool sema_expr_analyse_var_call(SemaContext *context, Expr *expr,
|
||||
*no_match_ref = true;
|
||||
return false;
|
||||
}
|
||||
RETURN_SEMA_ERROR(expr, "Only macros, functions and function pointers maybe invoked, this is of type '%s'.",
|
||||
RETURN_SEMA_ERROR(expr, "Only macros, functions and function pointers may be invoked, this is of type '%s'.",
|
||||
type_to_error_string(func_ptr_type));
|
||||
}
|
||||
Type *pointee = func_ptr_type->pointer;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
module output;
|
||||
module test;
|
||||
|
||||
def FnA = fn void(int*);
|
||||
distinct FnB = FnA;
|
||||
distinct FnC = inline FnA;
|
||||
|
||||
fn void func(int*) {}
|
||||
|
||||
@@ -11,4 +12,22 @@ fn void main()
|
||||
FnB b = (FnB)&func;
|
||||
FnB b2 = &func;
|
||||
FnB b3 = fn (int* x) {};
|
||||
}
|
||||
FnC c = &func;
|
||||
c(null);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
%a = alloca ptr, align 8
|
||||
%b = alloca ptr, align 8
|
||||
%b2 = alloca ptr, align 8
|
||||
%b3 = alloca ptr, align 8
|
||||
%c = alloca ptr, align 8
|
||||
store ptr @test.func, ptr %a, align 8
|
||||
store ptr @test.func, ptr %b, align 8
|
||||
store ptr @test.func, ptr %b2, align 8
|
||||
store ptr @"test.main$lambda1", ptr %b3, align 8
|
||||
store ptr @test.func, ptr %c, align 8
|
||||
%0 = load ptr, ptr %c, align 8
|
||||
call void %0(ptr null)
|
||||
ret void
|
||||
|
||||
16
test/test_suite/distinct/distinct_function_call.c3
Normal file
16
test/test_suite/distinct/distinct_function_call.c3
Normal file
@@ -0,0 +1,16 @@
|
||||
def Abc = fn void();
|
||||
distinct Foo = inline Abc;
|
||||
struct Bar
|
||||
{
|
||||
inline Abc a;
|
||||
}
|
||||
fn void test()
|
||||
{
|
||||
}
|
||||
fn void main()
|
||||
{
|
||||
Foo f = &test;
|
||||
Bar b = { &test };
|
||||
f();
|
||||
b(); // #error: may be invoked
|
||||
}
|
||||
Reference in New Issue
Block a user