mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Compiler segfault on global slice initialization with null[:0] #2404.
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
- Compile time indexing at compile time in a $typeof was no considered compile time.
|
||||
- Slicing a constant array with designated initialization would not update the indexes.
|
||||
- Fix for bug when `@format` encountered `*` in some cases.
|
||||
- Compiler segfault on global slice initialization with null[:0] #2404.
|
||||
|
||||
### Stdlib changes
|
||||
- Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`.
|
||||
|
||||
@@ -2638,19 +2638,26 @@ static void llvm_emit_slice_values(GenContext *c, Expr *slice, BEValue *parent_r
|
||||
ASSERT(slice->expr_kind == EXPR_SLICE);
|
||||
|
||||
Expr *parent_expr = exprptr(slice->subscript_expr.expr);
|
||||
|
||||
Type *parent_type = type_flatten(parent_expr->type);
|
||||
parent_type = type_no_optional(parent_type);
|
||||
BEValue parent_addr_x;
|
||||
llvm_emit_expr(c, &parent_addr_x, parent_expr);
|
||||
llvm_value_addr(c, &parent_addr_x);
|
||||
LLVMValueRef parent_addr = parent_addr_x.value;
|
||||
LLVMValueRef parent_load_value = NULL;
|
||||
LLVMValueRef parent_base;
|
||||
parent_type = type_no_optional(parent_type);
|
||||
LLVMValueRef parent_addr;
|
||||
if (parent_type->type_kind == TYPE_POINTER)
|
||||
{
|
||||
llvm_value_rvalue(c, &parent_addr_x);
|
||||
parent_load_value = parent_base = parent_addr_x.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
llvm_value_addr(c, &parent_addr_x);
|
||||
parent_addr = parent_addr_x.value;
|
||||
}
|
||||
switch (parent_type->type_kind)
|
||||
{
|
||||
case TYPE_POINTER:
|
||||
parent_load_value = parent_base = LLVMBuildLoad2(c->builder, llvm_get_type(c, parent_type), parent_addr, "");
|
||||
break;
|
||||
case TYPE_SLICE:
|
||||
parent_load_value = LLVMBuildLoad2(c->builder, llvm_get_type(c, parent_type), parent_addr, "");
|
||||
|
||||
19
test/test_suite/arrays/slice_null_const.c3t
Normal file
19
test/test_suite/arrays/slice_null_const.c3t
Normal file
@@ -0,0 +1,19 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
char[] bad @export = null[:0];
|
||||
|
||||
fn void main()
|
||||
{
|
||||
char[] good = null[:0];
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
@test__bad = local_unnamed_addr global %"char[]" zeroinitializer, align 8
|
||||
|
||||
define void @test.main() #0 {
|
||||
entry:
|
||||
%good = alloca %"char[]", align 8
|
||||
store %"char[]" zeroinitializer, ptr %good, align 8
|
||||
ret void
|
||||
}
|
||||
@@ -373,7 +373,6 @@ entry:
|
||||
%.inlinecache = alloca ptr, align 8
|
||||
%.cachedtype = alloca ptr, align 8
|
||||
%retparam = alloca ptr, align 8
|
||||
%taddr = alloca ptr, align 8
|
||||
%varargslots = alloca [1 x %any], align 16
|
||||
%indirectarg = alloca %"any[]", align 8
|
||||
%i = alloca i32, align 4
|
||||
@@ -467,79 +466,75 @@ after_check: ; preds = %match
|
||||
|
||||
expr_block.exit: ; preds = %after_check, %if.then
|
||||
%25 = load ptr, ptr %blockret11, align 8, !dbg !167
|
||||
store ptr %25, ptr %taddr, align 8
|
||||
%26 = load ptr, ptr %taddr, align 8
|
||||
%27 = load i64, ptr %elements8, align 8, !dbg !168
|
||||
%add = add i64 0, %27, !dbg !168
|
||||
%26 = load i64, ptr %elements8, align 8, !dbg !168
|
||||
%add = add i64 0, %26, !dbg !168
|
||||
%size13 = sub i64 %add, 0, !dbg !168
|
||||
%28 = insertvalue %"char[][]" undef, ptr %26, 0, !dbg !168
|
||||
%29 = insertvalue %"char[][]" %28, i64 %size13, 1, !dbg !168
|
||||
%27 = insertvalue %"char[][]" undef, ptr %25, 0, !dbg !168
|
||||
%28 = insertvalue %"char[][]" %27, i64 %size13, 1, !dbg !168
|
||||
br label %noerr_block, !dbg !168
|
||||
|
||||
panic_block: ; preds = %assign_optional
|
||||
%30 = insertvalue %any undef, ptr %error_var, 0, !dbg !168
|
||||
%31 = insertvalue %any %30, i64 ptrtoint (ptr @"$ct.fault" to i64), 1, !dbg !168
|
||||
store %any %31, ptr %varargslots, align 16
|
||||
%32 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %32, i64 1, 1
|
||||
%29 = insertvalue %any undef, ptr %error_var, 0, !dbg !168
|
||||
%30 = insertvalue %any %29, i64 ptrtoint (ptr @"$ct.fault" to i64), 1, !dbg !168
|
||||
store %any %30, ptr %varargslots, align 16
|
||||
%31 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %31, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %indirectarg, align 8
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg.1
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg.1, i64 36, ptr @.file, i64 16, ptr @.func, i64 6, i32 287, ptr byval(%"any[]") align 8 %indirectarg) #5, !dbg !157
|
||||
unreachable, !dbg !157
|
||||
|
||||
noerr_block: ; preds = %expr_block.exit
|
||||
store %"char[][]" %29, ptr %list5, align 8, !dbg !157
|
||||
|
||||
store %"char[][]" %28, ptr %list5, align 8, !dbg !157
|
||||
store i32 0, ptr %i, align 4, !dbg !172
|
||||
br label %loop.cond, !dbg !172
|
||||
|
||||
loop.cond: ; preds = %loop.exit, %noerr_block
|
||||
%33 = load i32, ptr %i, align 4, !dbg !173
|
||||
%34 = load i32, ptr %argc2, align 4, !dbg !174
|
||||
%lt = icmp slt i32 %33, %34, !dbg !173
|
||||
%32 = load i32, ptr %i, align 4, !dbg !173
|
||||
%33 = load i32, ptr %argc2, align 4, !dbg !174
|
||||
%lt = icmp slt i32 %32, %33, !dbg !173
|
||||
br i1 %lt, label %loop.body, label %loop.exit26, !dbg !173
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%35 = load ptr, ptr %argv3, align 8, !dbg !178
|
||||
%36 = load i32, ptr %i, align 4, !dbg !179
|
||||
%sext14 = sext i32 %36 to i64, !dbg !179
|
||||
%ptroffset = getelementptr inbounds [8 x i8], ptr %35, i64 %sext14, !dbg !179
|
||||
%37 = load ptr, ptr %ptroffset, align 8, !dbg !179
|
||||
store ptr %37, ptr %arg, align 8, !dbg !179
|
||||
|
||||
%34 = load ptr, ptr %argv3, align 8, !dbg !178
|
||||
%35 = load i32, ptr %i, align 4, !dbg !179
|
||||
%sext14 = sext i32 %35 to i64, !dbg !179
|
||||
%ptroffset = getelementptr inbounds [8 x i8], ptr %34, i64 %sext14, !dbg !179
|
||||
%36 = load ptr, ptr %ptroffset, align 8, !dbg !179
|
||||
store ptr %36, ptr %arg, align 8, !dbg !179
|
||||
store i64 0, ptr %len, align 8, !dbg !182
|
||||
%38 = load ptr, ptr %arg, align 8, !dbg !183
|
||||
%39 = load ptr, ptr %arg, align 8
|
||||
store ptr %39, ptr %ptr, align 8
|
||||
%37 = load ptr, ptr %arg, align 8, !dbg !183
|
||||
%38 = load ptr, ptr %arg, align 8
|
||||
store ptr %38, ptr %ptr, align 8
|
||||
store i64 0, ptr %len16, align 8, !dbg !188
|
||||
br label %loop.cond17, !dbg !189
|
||||
|
||||
loop.cond17: ; preds = %loop.body19, %loop.body
|
||||
%40 = load ptr, ptr %ptr, align 8, !dbg !190
|
||||
%41 = load i64, ptr %len16, align 8, !dbg !192
|
||||
%ptradd18 = getelementptr inbounds i8, ptr %40, i64 %41, !dbg !192
|
||||
%42 = load i8, ptr %ptradd18, align 1, !dbg !192
|
||||
%i2b = icmp ne i8 %42, 0, !dbg !192
|
||||
%39 = load ptr, ptr %ptr, align 8, !dbg !190
|
||||
%40 = load i64, ptr %len16, align 8, !dbg !192
|
||||
%ptradd18 = getelementptr inbounds i8, ptr %39, i64 %40, !dbg !192
|
||||
%41 = load i8, ptr %ptradd18, align 1, !dbg !192
|
||||
%i2b = icmp ne i8 %41, 0, !dbg !192
|
||||
br i1 %i2b, label %loop.body19, label %loop.exit, !dbg !192
|
||||
|
||||
loop.body19: ; preds = %loop.cond17
|
||||
%43 = load i64, ptr %len16, align 8, !dbg !193
|
||||
%add20 = add i64 %43, 1, !dbg !193
|
||||
%42 = load i64, ptr %len16, align 8, !dbg !193
|
||||
%add20 = add i64 %42, 1, !dbg !193
|
||||
store i64 %add20, ptr %len16, align 8, !dbg !193
|
||||
br label %loop.cond17, !dbg !193
|
||||
|
||||
loop.exit: ; preds = %loop.cond17
|
||||
%44 = load i64, ptr %len16, align 8, !dbg !194
|
||||
%add21 = add i64 0, %44, !dbg !194
|
||||
%43 = load i64, ptr %len16, align 8, !dbg !194
|
||||
%add21 = add i64 0, %43, !dbg !194
|
||||
%size22 = sub i64 %add21, 0, !dbg !194
|
||||
%45 = insertvalue %"char[]" undef, ptr %38, 0, !dbg !194
|
||||
%46 = insertvalue %"char[]" %45, i64 %size22, 1, !dbg !194
|
||||
%47 = load ptr, ptr %list5, align 8, !dbg !195
|
||||
%48 = load i32, ptr %i, align 4, !dbg !196
|
||||
%sext23 = sext i32 %48 to i64, !dbg !196
|
||||
%ptroffset24 = getelementptr inbounds [16 x i8], ptr %47, i64 %sext23, !dbg !196
|
||||
store %"char[]" %46, ptr %ptroffset24, align 8, !dbg !196
|
||||
%49 = load i32, ptr %i, align 4, !dbg !197
|
||||
%add25 = add i32 %49, 1, !dbg !197
|
||||
%44 = insertvalue %"char[]" undef, ptr %37, 0, !dbg !194
|
||||
%45 = insertvalue %"char[]" %44, i64 %size22, 1, !dbg !194
|
||||
%46 = load ptr, ptr %list5, align 8, !dbg !195
|
||||
%47 = load i32, ptr %i, align 4, !dbg !196
|
||||
%sext23 = sext i32 %47 to i64, !dbg !196
|
||||
%ptroffset24 = getelementptr inbounds [16 x i8], ptr %46, i64 %sext23, !dbg !196
|
||||
store %"char[]" %45, ptr %ptroffset24, align 8, !dbg !196
|
||||
%48 = load i32, ptr %i, align 4, !dbg !197
|
||||
%add25 = add i32 %48, 1, !dbg !197
|
||||
store i32 %add25, ptr %i, align 4, !dbg !197
|
||||
br label %loop.cond, !dbg !197
|
||||
|
||||
@@ -548,15 +543,15 @@ loop.exit26: ; preds = %loop.cond
|
||||
%lo = load ptr, ptr %list, align 8, !dbg !199
|
||||
%ptradd27 = getelementptr inbounds i8, ptr %list, i64 8, !dbg !199
|
||||
%hi = load i64, ptr %ptradd27, align 8, !dbg !199
|
||||
%50 = call i32 @test.main(ptr %lo, i64 %hi), !dbg !200
|
||||
store i32 %50, ptr %blockret, align 4, !dbg !200
|
||||
%51 = load ptr, ptr %list, align 8, !dbg !201
|
||||
call void @std.core.mem.free(ptr %51) #4, !dbg !203
|
||||
%49 = call i32 @test.main(ptr %lo, i64 %hi), !dbg !200
|
||||
store i32 %49, ptr %blockret, align 4, !dbg !200
|
||||
%50 = load ptr, ptr %list, align 8, !dbg !201
|
||||
call void @std.core.mem.free(ptr %50) #4, !dbg !203
|
||||
br label %expr_block.exit28, !dbg !203
|
||||
|
||||
expr_block.exit28: ; preds = %loop.exit26
|
||||
%52 = load i32, ptr %blockret, align 4, !dbg !203
|
||||
ret i32 %52, !dbg !203
|
||||
%51 = load i32, ptr %blockret, align 4, !dbg !203
|
||||
ret i32 %51, !dbg !203
|
||||
}
|
||||
|
||||
declare { i32, ptr } @attach.to_scope() #0
|
||||
|
||||
@@ -295,14 +295,13 @@ entry:
|
||||
%taddr4 = alloca %"char[]", align 8
|
||||
%taddr5 = alloca %"char[]", align 8
|
||||
%retparam = alloca ptr, align 8
|
||||
%taddr6 = alloca ptr, align 8
|
||||
%taddr6 = alloca %"char[]", align 8
|
||||
%taddr7 = alloca %"char[]", align 8
|
||||
%taddr8 = alloca %"char[]", align 8
|
||||
%taddr9 = alloca %"char[]", align 8
|
||||
%varargslots = alloca [1 x %any], align 8
|
||||
%taddr10 = alloca %"any[]", align 8
|
||||
%retparam14 = alloca %"char[]", align 8
|
||||
%taddr15 = alloca %"char[]", align 8
|
||||
%taddr9 = alloca %"any[]", align 8
|
||||
%retparam13 = alloca %"char[]", align 8
|
||||
%taddr14 = alloca %"char[]", align 8
|
||||
store ptr null, ptr %.cachedtype, align 8
|
||||
%0 = call ptr @llvm.threadlocal.address.p0(ptr @std.core.mem.allocator.thread_allocator)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %allocator, ptr align 8 %0, i32 16, i1 false)
|
||||
@@ -343,7 +342,7 @@ missing_function: ; preds = %6
|
||||
store %"char[]" { ptr @.func, i64 4 }, ptr %taddr5, align 8
|
||||
%10 = load [2 x i64], ptr %taddr5, align 8
|
||||
%11 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %11([2 x i64] %8, [2 x i64] %9, [2 x i64] %10,
|
||||
call void %11([2 x i64] %8, [2 x i64] %9, [2 x i64] %10, i32 98) #4
|
||||
unreachable
|
||||
|
||||
match: ; preds = %6
|
||||
@@ -359,60 +358,58 @@ assign_optional: ; preds = %match
|
||||
|
||||
after_check: ; preds = %match
|
||||
%15 = load ptr, ptr %retparam, align 8
|
||||
store ptr %15, ptr %taddr6, align 8
|
||||
%16 = load ptr, ptr %taddr6, align 8
|
||||
%17 = insertvalue %"char[]" undef, ptr %16, 0
|
||||
%18 = insertvalue %"char[]" %17, i64 12, 1
|
||||
%16 = insertvalue %"char[]" undef, ptr %15, 0
|
||||
%17 = insertvalue %"char[]" %16, i64 12, 1
|
||||
br label %noerr_block
|
||||
|
||||
panic_block: ; preds = %assign_optional
|
||||
%19 = insertvalue %any undef, ptr %error_var, 0
|
||||
%20 = insertvalue %any %19, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %"char[]" { ptr @.panic_msg.4, i64 36 }, ptr %taddr7, align 8
|
||||
%18 = insertvalue %any undef, ptr %error_var, 0
|
||||
%19 = insertvalue %any %18, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %"char[]" { ptr @.panic_msg.4, i64 36 }, ptr %taddr6, align 8
|
||||
%20 = load [2 x i64], ptr %taddr6, align 8
|
||||
store %"char[]" { ptr @.file, i64 16 }, ptr %taddr7, align 8
|
||||
%21 = load [2 x i64], ptr %taddr7, align 8
|
||||
store %"char[]" { ptr @.file, i64 16 }, ptr %taddr8, align 8
|
||||
store %"char[]" { ptr @.func, i64 4 }, ptr %taddr8, align 8
|
||||
%22 = load [2 x i64], ptr %taddr8, align 8
|
||||
store %"char[]" { ptr @.func, i64 4 }, ptr %taddr9, align 8
|
||||
%23 = load [2 x i64], ptr %taddr9, align 8
|
||||
store %any %20, ptr %varargslots, align 8
|
||||
%24 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %24, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %taddr10, align 8
|
||||
%25 = load [2 x i64], ptr %taddr10, align 8
|
||||
call void @std.core.builtin.panicf([2 x i64] %21, [2 x i64] %22, [2 x i64] %23,
|
||||
store %any %19, ptr %varargslots, align 8
|
||||
%23 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %23, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %taddr9, align 8
|
||||
%24 = load [2 x i64], ptr %taddr9, align 8
|
||||
call void @std.core.builtin.panicf([2 x i64] %20, [2 x i64] %21, [2 x i64] %22, i32 262, [2 x i64] %24) #4
|
||||
unreachable
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
store %"char[]" %18, ptr %buffer, align 8
|
||||
store %"char[]" %17, ptr %buffer, align 8
|
||||
store i64 0, ptr %buffer.f, align 8
|
||||
%optval = load i64, ptr %buffer.f, align 8
|
||||
%not_err11 = icmp eq i64 %optval, 0
|
||||
%26 = call i1 @llvm.expect.i1(i1 %not_err11, i1 true)
|
||||
br i1 %26, label %after_check13, label %assign_optional12
|
||||
%not_err10 = icmp eq i64 %optval, 0
|
||||
%25 = call i1 @llvm.expect.i1(i1 %not_err10, i1 true)
|
||||
br i1 %25, label %after_check12, label %assign_optional11
|
||||
|
||||
assign_optional12: ; preds = %noerr_block
|
||||
assign_optional11: ; preds = %noerr_block
|
||||
store i64 %optval, ptr %buffer.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_check13: ; preds = %noerr_block
|
||||
store %"char[]" { ptr @.str.5, i64 13 }, ptr %taddr15, align 8
|
||||
%27 = load [2 x i64], ptr %taddr15, align 8
|
||||
%28 = load [2 x i64], ptr %buffer, align 8
|
||||
%29 = call i64 @test.fileReader(ptr %retparam14, [2 x i64] %27, [2 x i64] %28)
|
||||
%not_err16 = icmp eq i64 %29, 0
|
||||
%30 = call i1 @llvm.expect.i1(i1 %not_err16, i1 true)
|
||||
br i1 %30, label %after_check18, label %assign_optional17
|
||||
after_check12: ; preds = %noerr_block
|
||||
store %"char[]" { ptr @.str.5, i64 13 }, ptr %taddr14, align 8
|
||||
%26 = load [2 x i64], ptr %taddr14, align 8
|
||||
%27 = load [2 x i64], ptr %buffer, align 8
|
||||
%28 = call i64 @test.fileReader(ptr %retparam13, [2 x i64] %26, [2 x i64] %27)
|
||||
%not_err15 = icmp eq i64 %28, 0
|
||||
%29 = call i1 @llvm.expect.i1(i1 %not_err15, i1 true)
|
||||
br i1 %29, label %after_check17, label %assign_optional16
|
||||
|
||||
assign_optional17: ; preds = %after_check13
|
||||
store i64 %29, ptr %buffer.f, align 8
|
||||
assign_optional16: ; preds = %after_check12
|
||||
store i64 %28, ptr %buffer.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_check18: ; preds = %after_check13
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %buffer, ptr align 8 %retparam14, i32 16, i1 false)
|
||||
after_check17: ; preds = %after_check12
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %buffer, ptr align 8 %retparam13, i32 16, i1 false)
|
||||
store i64 0, ptr %buffer.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_assign: ; preds = %after_check18, %assign_optional17, %assign_optional12
|
||||
after_assign: ; preds = %after_check17, %assign_optional16, %assign_optional11
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user