diff --git a/src/codegen.cpp b/src/codegen.cpp index 7fe4f95f85..7546416090 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2722,6 +2722,9 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstru } static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRef *instruction) { + if (!type_has_bits(instruction->base.value.type)) { + return nullptr; + } LLVMValueRef value = ir_llvm_value(g, instruction->value); if (handle_is_ptr(instruction->value->value.type)) { return value; @@ -3013,6 +3016,15 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst add_bounds_check(g, end_val, LLVMIntEQ, nullptr, LLVMIntULE, array_end); } } + if (!type_has_bits(array_type)) { + LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, ""); + + // TODO if debug safety is on, store 0xaaaaaaa in ptr field + LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); + gen_store_untyped(g, len_value, len_field_ptr, 0, false); + return tmp_struct_ptr; + } + LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_ptr_index, ""); LLVMValueRef indices[] = { diff --git a/src/ir.cpp b/src/ir.cpp index 7bd045bd92..db919350d1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7748,8 +7748,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *type_entry) { if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); - assert(fn_entry); - fn_entry->alloca_list.append(instruction); + if (fn_entry != nullptr) { + fn_entry->alloca_list.append(instruction); + } } } @@ -7851,9 +7852,7 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); result->value.type = wanted_type; if (need_alloca) { - FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); - if (fn_entry) - fn_entry->alloca_list.append(result); + ir_add_alloca(ira, result, wanted_type); } return result; } @@ -8287,6 +8286,7 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_ assert(fn_entry); fn_entry->alloca_list.append(new_instruction); } + ir_add_alloca(ira, new_instruction, child_type); return new_instruction; } } @@ -8330,13 +8330,15 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, is_const, is_volatile, get_abi_alignment(ira->codegen, value->value.type), 0, 0); - FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); - assert(fn_entry); IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, source_instruction->source_node, value, is_const, is_volatile); new_instruction->value.type = ptr_type; new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; - fn_entry->alloca_list.append(new_instruction); + if (type_has_bits(ptr_type)) { + FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); + assert(fn_entry); + fn_entry->alloca_list.append(new_instruction); + } return new_instruction; } diff --git a/test/cases/slice.zig b/test/cases/slice.zig index 44df8aa612..c47de5b09e 100644 --- a/test/cases/slice.zig +++ b/test/cases/slice.zig @@ -25,3 +25,12 @@ test "debug safety lets us slice from len..len" { fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) -> []u8 { return a_slice[start..end]; } + +test "implicitly cast array of size 0 to slice" { + var msg = []u8 {}; + assertLenIsZero(msg); +} + +fn assertLenIsZero(msg: []const u8) { + assert(msg.len == 0); +}