diff --git a/releasenotes.md b/releasenotes.md index 05937b625..8b13d91de 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -23,6 +23,7 @@ - Make `foo.$abc` implicitly mean `foo.eval("$abc")`. - Deprecating multi-level array length inference. `int[*][*]` is deprecated and will be removed 0.8.0. - Combining argument-less initialization with argument init for bitstructs is now allowed e.g. `{ .b, .c = 123 }`. +- Bug when initializing an inferred array with deep structure using designated init #2826 ### Fixes - Regression with npot vector in struct triggering an assert #2219. diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index 53fd17ba1..6b0f2cd18 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -523,7 +523,7 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type ArrayIndex max_index = -1; bool optional = false; Type *inner_type = NULL; - bool is_inferred = type_is_inferred(flattened); + bool is_inferred = type_is_infer_type(flattened); FOREACH(Expr *, expr, init_expressions) { Decl *member; @@ -552,17 +552,14 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type Type *type; if (!is_structlike && is_inferred) { - if (type_is_infer_type(flattened)) - { - type = type_from_inferred(flattened, inner_type, (ArraySize)(max_index + 1)); - } - else - { - type = type_from_inferred(flattened, inner_type, flattened->array.len); - } + type = type_from_inferred(flattened, flattened->array.base, (ArraySize)(max_index + 1)); } else { + if (!is_structlike && type_is_inferred(flattened)) + { + RETURN_SEMA_ERROR(initializer, "Inferring size when having non-top inferrence is not supported."); + } type = assigned; } if (splat && type->canonical != splat->type->canonical) diff --git a/test/test_suite/bitstruct/designated_init_infer.c3t b/test/test_suite/bitstruct/designated_init_infer.c3t new file mode 100644 index 000000000..cedccc3f1 --- /dev/null +++ b/test/test_suite/bitstruct/designated_init_infer.c3t @@ -0,0 +1,36 @@ +// #target: macos-x64 +module test; +union Union { int x; } +typedef Foo = Union; +union Union2 +{ + struct bar { Foo x; } +} +typedef Union3 = Union2; +typedef UnionArr = Union3[]; +fn UnionArr x() +{ + UnionArr a = { [0].bar.x.x = 3 }; + return a; +} +fn int main() +{ + return x()[0].bar.x.x; +} +/* #expect: test.ll + +@.__const = private unnamed_addr constant [1 x %Union2] [%Union2 { %bar { %Union { i32 3 } } }], align 4 + +define { ptr, i64 } @test.x() #0 { +entry: + %a = alloca %"Union2[]", align 8 + %literal = alloca [1 x %Union2], align 4 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal, ptr align 4 @.__const, i32 4, i1 false) + %0 = insertvalue %"Union2[]" undef, ptr %literal, 0 + %1 = insertvalue %"Union2[]" %0, i64 1, 1 + store %"Union2[]" %1, ptr %a, align 8 + %2 = load { ptr, i64 }, ptr %a, align 8 + ret { ptr, i64 } %2 +} + +