From af90da153178032df109aa955df0aac113de032d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 28 Aug 2019 12:16:52 -0400 Subject: fix implicit cast from zero sized array ptr to slice closes #1850 --- src/codegen.cpp | 28 ++++++++++++++++++---------- test/stage1/behavior/array.zig | 6 ++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index e8724f0d22..eda7a75d38 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3052,8 +3052,10 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *ex IrInstructionPtrOfArrayToSlice *instruction) { ZigType *actual_type = instruction->operand->value.type; - LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand); - assert(expr_val); + ZigType *slice_type = instruction->base.value.type; + ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry; + size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; + size_t len_index = slice_type->data.structure.fields[slice_len_index].gen_index; LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); @@ -3061,15 +3063,21 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *ex ZigType *array_type = actual_type->data.pointer.child_type; assert(array_type->id == ZigTypeIdArray); - LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_ptr_index, ""); - LLVMValueRef indices[] = { - LLVMConstNull(g->builtin_types.entry_usize->llvm_type), - LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false), - }; - LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, ""); - gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); + if (type_has_bits(actual_type)) { + LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); + LLVMValueRef indices[] = { + LLVMConstNull(g->builtin_types.entry_usize->llvm_type), + LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false), + }; + LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand); + LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, ""); + gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); + } else if (ir_want_runtime_safety(g, &instruction->base)) { + LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); + gen_undef_init(g, slice_ptr_type->abi_align, slice_ptr_type, ptr_field_ptr); + } - LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_len_index, ""); + LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, ""); LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false); gen_store_untyped(g, len_value, len_field_ptr, 0, false); diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 9349af573c..462977066e 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -292,3 +292,9 @@ test "read/write through global variable array of struct fields initialized via }; S.doTheTest(); } + +test "implicit cast zero sized array ptr to slice" { + var b = ""; + const c: []const u8 = &b; + expect(c.len == 0); +} -- cgit v1.2.3