From a99e4b602a25f7ded5f53fea2525c300b011d765 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 27 Sep 2024 13:10:48 +0200 Subject: [PATCH] Error when slicing a struct with an inline array #1488. --- releasenotes.md | 1 + src/compiler/sema_expr.c | 5 +++- test/test_suite/slices/slice_inline.c3t | 34 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/test_suite/slices/slice_inline.c3t diff --git a/releasenotes.md b/releasenotes.md index 6e0029a86..3a26d7216 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -62,6 +62,7 @@ - Regression when compile time accessing a union field not last assigned to. - Safer seed of rand() for WASM without libc. - Bad error message aliasing an ident with a path. #1481. +- Error when slicing a struct with an inline array #1488. ### Stdlib changes - Additional init functions for hashmap. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index bf9249d1e..971e63532 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -3357,13 +3357,16 @@ static inline bool sema_expr_analyse_slice(SemaContext *context, Expr *expr, Che } Expr *current_expr = subscripted; Type *inner_type = sema_subscript_find_indexable_type_recursively(&type, ¤t_expr); - if (type == type_voidptr) inner_type = type_char; if (!inner_type || !type_is_valid_for_array(inner_type)) { RETURN_SEMA_ERROR(subscripted, "Cannot index %s.", type_quoted_error_string(subscripted->type)); } + if (current_expr != subscripted) + { + expr->slice_expr.expr = exprid(current_expr); + } // Retain the original type when doing distinct slices. Type *result_type = type_get_slice(inner_type); Type *original_type_canonical = original_type->canonical; diff --git a/test/test_suite/slices/slice_inline.c3t b/test/test_suite/slices/slice_inline.c3t new file mode 100644 index 000000000..5e395737f --- /dev/null +++ b/test/test_suite/slices/slice_inline.c3t @@ -0,0 +1,34 @@ +// #target: macos-x64 +module foo; +struct Data{ + inline char[32] data; +} +fn void Data.not_working(self) { + self[:self.data.len]; +} + +fn void Data.working(self) { + self.data[:self.data.len]; +} +fn void! main(String[] args) { + Data d; + d.not_working(); + d.working(); +} + +/* #expect: foo.ll + +define void @foo.Data.not_working(ptr byval(%Data) align 8 %0) #0 { +entry: + %1 = insertvalue %"char[]" undef, ptr %0, 0 + %2 = insertvalue %"char[]" %1, i64 32, 1 + ret void +} +; Function Attrs: nounwind uwtable +define void @foo.Data.working(ptr byval(%Data) align 8 %0) #0 { +entry: + %1 = insertvalue %"char[]" undef, ptr %0, 0 + %2 = insertvalue %"char[]" %1, i64 32, 1 + ret void +} +