mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Indexing an Optional slice would crash in codegen #1636.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
41
test/test_suite/slices/slice_optional.c3t
Normal file
41
test/test_suite/slices/slice_optional.c3t
Normal file
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user