From 347a1a48d47bfb87c91cf0a95441ac7535d0b957 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 21 Nov 2024 11:30:53 +0100 Subject: [PATCH] Indexing an Optional slice would crash in codegen #1636. --- releasenotes.md | 1 + src/compiler/llvm_codegen_expr.c | 7 ++-- src/compiler/llvm_codegen_internal.h | 2 +- .../{subarrays => slices}/slice_checks.c3t | 0 .../slice_comparison.c3t | 0 .../{subarrays => slices}/slice_conv_byte.c3t | 0 .../slice_negative_len.c3 | 0 .../{subarrays => slices}/slice_offset.c3t | 0 .../slice_offset_neg_end.c3t | 0 .../slice_offset_neg_start.c3t | 0 test/test_suite/slices/slice_optional.c3t | 41 +++++++++++++++++++ .../{subarrays => slices}/slice_start.c3t | 0 .../{subarrays => slices}/slice_syntax.c3 | 0 .../{subarrays => slices}/sub_array_init.c3 | 0 .../subscript_check_1519.c3t | 0 15 files changed, 47 insertions(+), 4 deletions(-) rename test/test_suite/{subarrays => slices}/slice_checks.c3t (100%) rename test/test_suite/{subarrays => slices}/slice_comparison.c3t (100%) rename test/test_suite/{subarrays => slices}/slice_conv_byte.c3t (100%) rename test/test_suite/{subarrays => slices}/slice_negative_len.c3 (100%) rename test/test_suite/{subarrays => slices}/slice_offset.c3t (100%) rename test/test_suite/{subarrays => slices}/slice_offset_neg_end.c3t (100%) rename test/test_suite/{subarrays => slices}/slice_offset_neg_start.c3t (100%) create mode 100644 test/test_suite/slices/slice_optional.c3t rename test/test_suite/{subarrays => slices}/slice_start.c3t (100%) rename test/test_suite/{subarrays => slices}/slice_syntax.c3 (100%) rename test/test_suite/{subarrays => slices}/sub_array_init.c3 (100%) rename test/test_suite/{subarrays => slices}/subscript_check_1519.c3t (100%) diff --git a/releasenotes.md b/releasenotes.md index 2593d7644..bc811aa6a 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -17,6 +17,7 @@ - Fix issue with resolved try-unwrap in defer. - Fix issue with overloaded subscript and ++/--. - Fix issue with properties in different targets not being respected #1633. +- Indexing an Optional slice would crash in codegen #1636. ### Stdlib changes - Add `io::MultiReader`, `io::MultiWriter`, and `io::TeeReader` structs. diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index bca2d8355..a444ee94a 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -5399,18 +5399,19 @@ void llvm_emit_slice_len(GenContext *c, BEValue *slice, BEValue *len) llvm_value_set_address(len, len_addr, type_usz, alignment); } -void llvm_emit_slice_pointer(GenContext *context, BEValue *slice, BEValue *pointer) +void llvm_emit_slice_pointer(GenContext *c, BEValue *slice, BEValue *pointer) { ASSERT0(slice->type->type_kind == TYPE_SLICE); Type *ptr_type = type_get_ptr(slice->type->array.base); + llvm_value_fold_optional(c, slice); if (slice->kind == BE_ADDRESS) { AlignSize alignment; - LLVMValueRef ptr = llvm_emit_struct_gep_raw(context, slice->value, llvm_get_type(context, slice->type), 0, slice->alignment, &alignment); + LLVMValueRef ptr = llvm_emit_struct_gep_raw(c, slice->value, llvm_get_type(c, slice->type), 0, slice->alignment, &alignment); llvm_value_set_address(pointer, ptr, ptr_type, alignment); return; } - LLVMValueRef ptr = llvm_emit_extract_value(context, slice->value, 0); + LLVMValueRef ptr = llvm_emit_extract_value(c, slice->value, 0); llvm_value_set(pointer, ptr, ptr_type); } diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index 4766453cc..21143b017 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -529,7 +529,7 @@ LLVMValueRef llvm_emit_expect_raw(GenContext *c, LLVMValueRef expect_true); LLVMValueRef llvm_emit_expect_false(GenContext *c, BEValue *expect_false); void llvm_emit_any_from_value(GenContext *c, BEValue *value, Type *type); void llvm_emit_slice_len(GenContext *c, BEValue *slice, BEValue *len); -void llvm_emit_slice_pointer(GenContext *context, BEValue *slice, BEValue *pointer); +void llvm_emit_slice_pointer(GenContext *c, BEValue *slice, BEValue *pointer); void llvm_emit_compound_stmt(GenContext *c, Ast *ast); LLVMValueRef llvm_emit_const_bitstruct(GenContext *c, ConstInitializer *initializer); void llvm_emit_function_body(GenContext *context, Decl *decl); diff --git a/test/test_suite/subarrays/slice_checks.c3t b/test/test_suite/slices/slice_checks.c3t similarity index 100% rename from test/test_suite/subarrays/slice_checks.c3t rename to test/test_suite/slices/slice_checks.c3t diff --git a/test/test_suite/subarrays/slice_comparison.c3t b/test/test_suite/slices/slice_comparison.c3t similarity index 100% rename from test/test_suite/subarrays/slice_comparison.c3t rename to test/test_suite/slices/slice_comparison.c3t diff --git a/test/test_suite/subarrays/slice_conv_byte.c3t b/test/test_suite/slices/slice_conv_byte.c3t similarity index 100% rename from test/test_suite/subarrays/slice_conv_byte.c3t rename to test/test_suite/slices/slice_conv_byte.c3t diff --git a/test/test_suite/subarrays/slice_negative_len.c3 b/test/test_suite/slices/slice_negative_len.c3 similarity index 100% rename from test/test_suite/subarrays/slice_negative_len.c3 rename to test/test_suite/slices/slice_negative_len.c3 diff --git a/test/test_suite/subarrays/slice_offset.c3t b/test/test_suite/slices/slice_offset.c3t similarity index 100% rename from test/test_suite/subarrays/slice_offset.c3t rename to test/test_suite/slices/slice_offset.c3t diff --git a/test/test_suite/subarrays/slice_offset_neg_end.c3t b/test/test_suite/slices/slice_offset_neg_end.c3t similarity index 100% rename from test/test_suite/subarrays/slice_offset_neg_end.c3t rename to test/test_suite/slices/slice_offset_neg_end.c3t diff --git a/test/test_suite/subarrays/slice_offset_neg_start.c3t b/test/test_suite/slices/slice_offset_neg_start.c3t similarity index 100% rename from test/test_suite/subarrays/slice_offset_neg_start.c3t rename to test/test_suite/slices/slice_offset_neg_start.c3t diff --git a/test/test_suite/slices/slice_optional.c3t b/test/test_suite/slices/slice_optional.c3t new file mode 100644 index 000000000..bc6545de6 --- /dev/null +++ b/test/test_suite/slices/slice_optional.c3t @@ -0,0 +1,41 @@ +// #target: macos-x64 +module test; +fn void main() { + int[]! a = {1, 2}; + int! b = a[0]; +} + +/* #expect: test.ll + +define void @test.main() #0 { +entry: + %a = alloca %"int[]", align 8 + %a.f = alloca i64, align 8 + %literal = alloca [2 x i32], align 4 + %b = alloca i32, align 4 + %b.f = alloca i64, align 8 + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal, ptr align 4 @.__const, i32 8, i1 false) + %0 = insertvalue %"int[]" undef, ptr %literal, 0 + %1 = insertvalue %"int[]" %0, i64 2, 1 + store %"int[]" %1, ptr %a, align 8 + store i64 0, ptr %a.f, align 8 + %optval = load i64, ptr %a.f, align 8 + %not_err = icmp eq i64 %optval, 0 + %2 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) + br i1 %2, label %after_check, label %assign_optional + +assign_optional: ; preds = %entry + store i64 %optval, ptr %b.f, align 8 + br label %after_assign + +after_check: ; preds = %entry + %3 = load ptr, ptr %a, align 8 + %4 = load i32, ptr %3, align 4 + store i32 %4, ptr %b, align 4 + store i64 0, ptr %b.f, align 8 + br label %after_assign + +after_assign: ; preds = %after_check, %assign_optional + ret void +} + diff --git a/test/test_suite/subarrays/slice_start.c3t b/test/test_suite/slices/slice_start.c3t similarity index 100% rename from test/test_suite/subarrays/slice_start.c3t rename to test/test_suite/slices/slice_start.c3t diff --git a/test/test_suite/subarrays/slice_syntax.c3 b/test/test_suite/slices/slice_syntax.c3 similarity index 100% rename from test/test_suite/subarrays/slice_syntax.c3 rename to test/test_suite/slices/slice_syntax.c3 diff --git a/test/test_suite/subarrays/sub_array_init.c3 b/test/test_suite/slices/sub_array_init.c3 similarity index 100% rename from test/test_suite/subarrays/sub_array_init.c3 rename to test/test_suite/slices/sub_array_init.c3 diff --git a/test/test_suite/subarrays/subscript_check_1519.c3t b/test/test_suite/slices/subscript_check_1519.c3t similarity index 100% rename from test/test_suite/subarrays/subscript_check_1519.c3t rename to test/test_suite/slices/subscript_check_1519.c3t