- Optional in initializer cause a crash #2864

- Negating a global address with offset was a counted as a global runtime constant #2865
- Converting static "make_slice" to array failed to be handled #2866
- Narrowing a not expression was incorrectly handled #2867
- Vector shift by optional scalar failed #2868
This commit is contained in:
Christoffer Lerno
2026-01-28 21:59:40 +01:00
parent fed7a74a75
commit 362d5680e4
11 changed files with 215 additions and 4 deletions

View File

@@ -0,0 +1,36 @@
// #target: macos-x64
module test;
import std;
fn int[3] test()
{
int[3] x = io::EOF~!!;
return (int[])&x;
}
fn int main()
{
test();
return 0;
}
/* #expect: test.ll
define { i64, i32 } @test.test() #0 {
entry:
%x = alloca [3 x i32], align 4
%error_var = alloca i64, align 8
%varargslots = alloca [1 x %any], align 16
%indirectarg = alloca %"any[]", align 8
store i64 ptrtoint (ptr @std.io.EOF to i64), ptr %error_var, align 8
br label %panic_block
panic_block: ; preds = %entry
%0 = insertvalue %any undef, ptr %error_var, 0
%1 = insertvalue %any %0, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
store %any %1, ptr %varargslots, align 16
%2 = insertvalue %"any[]" undef, ptr %varargslots, 0
%"$$temp" = insertvalue %"any[]" %2, i64 1, 1
store %"any[]" %"$$temp", ptr %indirectarg, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 35, ptr @.func, i64 4, i32 5, ptr byval(%"any[]") align 8 %indirectarg) #2
unreachable
}

View File

@@ -0,0 +1,8 @@
<* @require main.kindof == SIGNED_INT *>
struct Foo <Type>
{}
fn int main()
{
Foo{double} d; // #error: Parameter(s) failed validation: @require "main.kindof == SIGNED_INT" violated
}

View File

@@ -0,0 +1,31 @@
// #target: macos-x64
module test;
fn void main()
{
ulong[1] haystack;
ulong[1] needle;
uint is_found = 0;
is_found += (ulong)~!(haystack[0] == needle[0]);
}
/* #expect: test.ll
define void @test.main() #0 {
entry:
%haystack = alloca [1 x i64], align 8
%needle = alloca [1 x i64], align 8
%is_found = alloca i32, align 4
store i64 0, ptr %haystack, align 8
store i64 0, ptr %needle, align 8
store i32 0, ptr %is_found, align 4
%0 = load i32, ptr %is_found, align 4
%1 = load i64, ptr %haystack, align 8
%2 = load i64, ptr %needle, align 8
%eq = icmp eq i64 %1, %2
%not = xor i1 %eq, true
%bnot = xor i1 %not, true
%zext = zext i1 %bnot to i64
%trunc = trunc i64 %zext to i32
%add = add i32 %0, %trunc
store i32 %add, ptr %is_found, align 4
ret void
}

View File

@@ -0,0 +1,75 @@
// #target: macos-x64
module abc <Type>;
import std::io, std::collections::list;
struct TextTemplate
{
Allocator allocator;
String template;
}
fn void? TextTemplate.init(&self, String , String tag_start = "", String tag_end = "", Allocator using )
{
*self = { .allocator = using, .template = io::EOF~!, };
}
module text_test;
import abc;
alias FooTmpl = TextTemplate{Foo};
alias BarTmpl = TextTemplate{Bar};
struct Foo { BarTmpl bar; }
struct Bar { String bar; }
fn void main()
{
String foo_tmpl = "";
FooTmpl ft;
ft.init(foo_tmpl, using: tmem)!!;
}
/* #expect: abc.ll
@std.io.EOF = linkonce constant %"char[]" { ptr @std.io.EOF.nameof, i64 7 }, align 8
@std.io.EOF.nameof = internal constant [8 x i8] c"io::EOF\00", align 1
define weak i64 @"abc.TextTemplate$text_test.Foo$.init"(ptr %0, ptr %1, i64 %2, ptr %3, i64 %4, ptr byval(%"char[]") align 8 %5, ptr byval(%any) align 8 %6) #0 {
entry:
%.anon = alloca %"char[]", align 8
%tag_start = alloca %"char[]", align 8
%.assign_list = alloca %"TextTemplate{Foo}", align 8
%error_var = alloca i64, align 8
store ptr %1, ptr %.anon, align 8
%ptradd = getelementptr inbounds i8, ptr %.anon, i64 8
store i64 %2, ptr %ptradd, align 8
store ptr %3, ptr %tag_start, align 8
%ptradd1 = getelementptr inbounds i8, ptr %tag_start, i64 8
store i64 %4, ptr %ptradd1, align 8
call void @llvm.memset.p0.i64(ptr align 8 %.assign_list, i8 0, i64 32, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %.assign_list, ptr align 8 %6, i32 16, i1 false)
%ptradd2 = getelementptr inbounds i8, ptr %.assign_list, i64 16
store i64 ptrtoint (ptr @std.io.EOF to i64), ptr %error_var, align 8
br label %guard_block
guard_block: ; preds = %entry
%7 = load i64, ptr %error_var, align 8
ret i64 %7
}
define weak i64 @"abc.TextTemplate$text_test.Bar$.init"(ptr %0, ptr %1, i64 %2, ptr %3, i64 %4, ptr byval(%"char[]") align 8 %5, ptr byval(%any) align 8 %6) #0 {
entry:
%.anon = alloca %"char[]", align 8
%tag_start = alloca %"char[]", align 8
%.assign_list = alloca %"TextTemplate{Bar}", align 8
%error_var = alloca i64, align 8
store ptr %1, ptr %.anon, align 8
%ptradd = getelementptr inbounds i8, ptr %.anon, i64 8
store i64 %2, ptr %ptradd, align 8
store ptr %3, ptr %tag_start, align 8
%ptradd1 = getelementptr inbounds i8, ptr %tag_start, i64 8
store i64 %4, ptr %ptradd1, align 8
call void @llvm.memset.p0.i64(ptr align 8 %.assign_list, i8 0, i64 32, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %.assign_list, ptr align 8 %6, i32 16, i1 false)
%ptradd2 = getelementptr inbounds i8, ptr %.assign_list, i64 16
store i64 ptrtoint (ptr @std.io.EOF to i64), ptr %error_var, align 8
br label %guard_block
guard_block: ; preds = %entry
%7 = load i64, ptr %error_var, align 8
ret i64 %7
}

View File

@@ -0,0 +1,42 @@
// #target: macos-x64
module test;
typedef Foo = inline int;
fn int main()
{
Foo? u = 2;
int[<2>]? f4 = (int[<2>]) { 1, 2 } << u;
return 0;
}
/* #expect: test.ll
define i32 @main() #0 {
entry:
%u = alloca i32, align 4
%u.f = alloca i64, align 8
%f4 = alloca <2 x i32>, align 8
%f4.f = alloca i64, align 8
store i32 2, ptr %u, align 4
store i64 0, ptr %u.f, align 8
%optval = load i64, ptr %u.f, align 8
%not_err = icmp eq i64 %optval, 0
%0 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %0, label %after_check, label %assign_optional
assign_optional: ; preds = %entry
store i64 %optval, ptr %f4.f, align 8
br label %after_assign
after_check: ; preds = %entry
%1 = load i32, ptr %u, align 4
%2 = insertelement <2 x i32> undef, i32 %1, i64 0
%3 = insertelement <2 x i32> %2, i32 %1, i64 1
%shl = shl <2 x i32> <i32 1, i32 2>, %3
%4 = freeze <2 x i32> %shl
store <2 x i32> %4, ptr %f4, align 8
store i64 0, ptr %f4.f, align 8
br label %after_assign
after_assign: ; preds = %after_check, %assign_optional
ret i32 0
}