Assert when partially initializing a constant struct containing a slice #1812.

This commit is contained in:
Christoffer Lerno
2025-01-11 22:42:33 +01:00
parent c8fa7b0cb3
commit 8785c2c46f
3 changed files with 43 additions and 6 deletions

View File

@@ -76,6 +76,7 @@
- Fix bug preventing compile time slices from being iterated over with `$foreach`.
- Fix bug with defer assignment in macro #1807.
- Fix regression with swizzle references for vectors #1810.
- Assert when partially initializing a constant struct containing a slice #1812.
### Stdlib changes
- Increase BitWriter.write_bits limit up to 32 bits.

View File

@@ -233,21 +233,20 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_
switch (const_init->kind)
{
case CONST_INIT_ZERO:
ASSERT0(const_init->type->type_kind != TYPE_SLICE);
return llvm_get_zero(c, const_init->type);
case CONST_INIT_ARRAY_VALUE:
UNREACHABLE
case CONST_INIT_ARRAY_FULL:
{
ASSERT0(const_init->type->type_kind != TYPE_SLICE);
ASSERT(const_init, const_init->type->type_kind != TYPE_SLICE);
bool was_modified = false;
Type *array_type = const_init->type;
Type *element_type = array_type->array.base;
LLVMTypeRef element_type_llvm = llvm_get_type(c, element_type);
ConstInitializer **elements = const_init->init_array_full;
ASSERT0(array_type->type_kind == TYPE_ARRAY || array_type->type_kind == TYPE_VECTOR);
ASSERT(const_init, array_type->type_kind == TYPE_ARRAY || array_type->type_kind == TYPE_VECTOR);
ArraySize size = array_type->array.len;
ASSERT0(size > 0);
ASSERT(const_init, size > 0);
LLVMValueRef *parts = VECNEW(LLVMValueRef, size);
for (ArrayIndex i = 0; i < (ArrayIndex)size; i++)
{
@@ -268,14 +267,14 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_
case CONST_INIT_ARRAY:
{
ASSERT0(const_init->type->type_kind != TYPE_SLICE);
ASSERT(const_init, const_init->type->type_kind != TYPE_SLICE);
bool was_modified = false;
Type *array_type = const_init->type;
Type *element_type = array_type->array.base;
LLVMTypeRef element_type_llvm = llvm_get_type(c, element_type);
AlignSize expected_align = llvm_abi_alignment(c, element_type_llvm);
ConstInitializer **elements = const_init->init_array.elements;
ASSERT0(vec_size(elements) > 0 && "Array should always have gotten at least one element.");
ASSERT(const_init, vec_size(elements) > 0 && "Array should always have gotten at least one element.");
ArrayIndex current_index = 0;
unsigned alignment = 0;
LLVMValueRef *parts = NULL;

View File

@@ -0,0 +1,37 @@
// #target: macos-x64
module test;
// Issue #1812
struct Foo
{
float a;
String b;
}
struct Bar
{
float a;
int[] b;
}
const Foo FOO = {.a = 1};
const Bar FOO2 = {.a = 1, .b = { 1, 3 } };
fn int main()
{
Foo asdf = FOO;
Bar foek = FOO2;
return 0;
}
/* #expect: test.ll
@test.FOO = local_unnamed_addr constant %Foo { float 1.000000e+00, %"char[]" zeroinitializer }, align 8
@.__const_slice = private unnamed_addr global [2 x i32] [i32 1, i32 3], align 4
@test.FOO2 = local_unnamed_addr constant %Bar { float 1.000000e+00, %"int[]" { ptr @.__const_slice, i64 2 } }, align 8
entry:
%asdf = alloca %Foo, align 8
%foek = alloca %Bar, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %asdf, ptr align 8 @test.FOO, i32 24, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %foek, ptr align 8 @test.FOO2, i32 24, i1 false)
ret i32 0
}