mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Compile time switch over type would not correctly compare function pointer types.
This commit is contained in:
@@ -108,7 +108,7 @@ macro anycast(any v, $Type) @builtin
|
|||||||
return ($Type*)v.ptr;
|
return ($Type*)v.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro bool @assignable_to(#foo, $Type) @const @builtin @deprecated("use '$define($Type x = #foo)'") => $defined(*&&($Type){} = #foo);
|
macro bool @assignable_to(#foo, $Type) @const @builtin @deprecated("use '$defined($Type x = #foo)'") => $defined(*&&($Type){} = #foo);
|
||||||
|
|
||||||
macro @addr(#val) @builtin
|
macro @addr(#val) @builtin
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
- `??` with void results on both sides cause a compiler crash #2472.
|
- `??` with void results on both sides cause a compiler crash #2472.
|
||||||
- Stack object size limit error on a static object. #2476
|
- Stack object size limit error on a static object. #2476
|
||||||
- Compiler segfault when modifying variable using an inline assembly block inside defer #2450.
|
- Compiler segfault when modifying variable using an inline assembly block inside defer #2450.
|
||||||
|
- Compile time switch over type would not correctly compare function pointer types.
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
- Added generic `InterfaceList` to store a list of values that implement a specific interface
|
- Added generic `InterfaceList` to store a list of values that implement a specific interface
|
||||||
|
|||||||
@@ -1598,6 +1598,10 @@ bool type_is_subtype(Type *type, Type *possible_subtype)
|
|||||||
{
|
{
|
||||||
possible_subtype = possible_subtype->canonical;
|
possible_subtype = possible_subtype->canonical;
|
||||||
if (type == possible_subtype) return true;
|
if (type == possible_subtype) return true;
|
||||||
|
if (type->type_kind == TYPE_FUNC_PTR && possible_subtype->type_kind == TYPE_FUNC_PTR)
|
||||||
|
{
|
||||||
|
return type->pointer->function.prototype->raw_type == possible_subtype->pointer->function.prototype->raw_type;
|
||||||
|
}
|
||||||
possible_subtype = type_find_parent_type(possible_subtype);
|
possible_subtype = type_find_parent_type(possible_subtype);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
92
test/test_suite/compile_time/ct_switch_fn.c3t
Normal file
92
test/test_suite/compile_time/ct_switch_fn.c3t
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// #target: macos-x64
|
||||||
|
module test;
|
||||||
|
import std;
|
||||||
|
|
||||||
|
alias Foo = fn void();
|
||||||
|
|
||||||
|
macro @test(#foo)
|
||||||
|
{
|
||||||
|
$switch $typeof(#foo):
|
||||||
|
$case Foo:
|
||||||
|
io::printn("Hello");
|
||||||
|
$default:
|
||||||
|
io::printn($typeof(#foo).nameof);
|
||||||
|
$endswitch
|
||||||
|
}
|
||||||
|
fn void tester() {}
|
||||||
|
fn int main(String[] args)
|
||||||
|
{
|
||||||
|
@test(&tester);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* #expect: test.ll
|
||||||
|
|
||||||
|
define i32 @test.main(ptr %0, i64 %1) #0 {
|
||||||
|
entry:
|
||||||
|
%args = alloca %"char[][]", align 8
|
||||||
|
%len = alloca i64, align 8
|
||||||
|
%error_var = alloca i64, align 8
|
||||||
|
%retparam = alloca i64, align 8
|
||||||
|
%error_var2 = alloca i64, align 8
|
||||||
|
%error_var8 = alloca i64, align 8
|
||||||
|
store ptr %0, ptr %args, align 8
|
||||||
|
%ptradd = getelementptr inbounds i8, ptr %args, i64 8
|
||||||
|
store i64 %1, ptr %ptradd, align 8
|
||||||
|
%2 = call ptr @std.io.stdout()
|
||||||
|
%3 = call i64 @std.io.File.write(ptr %retparam, ptr %2, ptr @.str, i64 5)
|
||||||
|
%not_err = icmp eq i64 %3, 0
|
||||||
|
%4 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||||
|
br i1 %4, label %after_check, label %assign_optional
|
||||||
|
|
||||||
|
assign_optional: ; preds = %entry
|
||||||
|
store i64 %3, ptr %error_var, align 8
|
||||||
|
br label %guard_block
|
||||||
|
|
||||||
|
after_check: ; preds = %entry
|
||||||
|
br label %noerr_block
|
||||||
|
|
||||||
|
guard_block: ; preds = %assign_optional
|
||||||
|
br label %voiderr
|
||||||
|
|
||||||
|
noerr_block: ; preds = %after_check
|
||||||
|
%5 = load i64, ptr %retparam, align 8
|
||||||
|
store i64 %5, ptr %len, align 8
|
||||||
|
%6 = call i64 @std.io.File.write_byte(ptr %2, i8 zeroext 10)
|
||||||
|
%not_err3 = icmp eq i64 %6, 0
|
||||||
|
%7 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
|
||||||
|
br i1 %7, label %after_check5, label %assign_optional4
|
||||||
|
|
||||||
|
assign_optional4: ; preds = %noerr_block
|
||||||
|
store i64 %6, ptr %error_var2, align 8
|
||||||
|
br label %guard_block6
|
||||||
|
|
||||||
|
after_check5: ; preds = %noerr_block
|
||||||
|
br label %noerr_block7
|
||||||
|
|
||||||
|
guard_block6: ; preds = %assign_optional4
|
||||||
|
br label %voiderr
|
||||||
|
|
||||||
|
noerr_block7: ; preds = %after_check5
|
||||||
|
%8 = call i64 @std.io.File.flush(ptr %2)
|
||||||
|
%not_err9 = icmp eq i64 %8, 0
|
||||||
|
%9 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true)
|
||||||
|
br i1 %9, label %after_check11, label %assign_optional10
|
||||||
|
|
||||||
|
assign_optional10: ; preds = %noerr_block7
|
||||||
|
store i64 %8, ptr %error_var8, align 8
|
||||||
|
br label %guard_block12
|
||||||
|
|
||||||
|
after_check11: ; preds = %noerr_block7
|
||||||
|
br label %noerr_block13
|
||||||
|
|
||||||
|
guard_block12: ; preds = %assign_optional10
|
||||||
|
br label %voiderr
|
||||||
|
|
||||||
|
noerr_block13: ; preds = %after_check11
|
||||||
|
%10 = load i64, ptr %len, align 8
|
||||||
|
%add = add i64 %10, 1
|
||||||
|
br label %voiderr
|
||||||
|
|
||||||
|
voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user