Skip to content

Commit af90da1

Browse files
committed
fix implicit cast from zero sized array ptr to slice
closes ziglang#1850
1 parent d5b3d97 commit af90da1

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

src/codegen.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3052,24 +3052,32 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *ex
30523052
IrInstructionPtrOfArrayToSlice *instruction)
30533053
{
30543054
ZigType *actual_type = instruction->operand->value.type;
3055-
LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
3056-
assert(expr_val);
3055+
ZigType *slice_type = instruction->base.value.type;
3056+
ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;
3057+
size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
3058+
size_t len_index = slice_type->data.structure.fields[slice_len_index].gen_index;
30573059

30583060
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
30593061

30603062
assert(actual_type->id == ZigTypeIdPointer);
30613063
ZigType *array_type = actual_type->data.pointer.child_type;
30623064
assert(array_type->id == ZigTypeIdArray);
30633065

3064-
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_ptr_index, "");
3065-
LLVMValueRef indices[] = {
3066-
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
3067-
LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
3068-
};
3069-
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
3070-
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
3066+
if (type_has_bits(actual_type)) {
3067+
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, "");
3068+
LLVMValueRef indices[] = {
3069+
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
3070+
LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
3071+
};
3072+
LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
3073+
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
3074+
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
3075+
} else if (ir_want_runtime_safety(g, &instruction->base)) {
3076+
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, "");
3077+
gen_undef_init(g, slice_ptr_type->abi_align, slice_ptr_type, ptr_field_ptr);
3078+
}
30713079

3072-
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_len_index, "");
3080+
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, "");
30733081
LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
30743082
array_type->data.array.len, false);
30753083
gen_store_untyped(g, len_value, len_field_ptr, 0, false);

test/stage1/behavior/array.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,9 @@ test "read/write through global variable array of struct fields initialized via
292292
};
293293
S.doTheTest();
294294
}
295+
296+
test "implicit cast zero sized array ptr to slice" {
297+
var b = "";
298+
const c: []const u8 = &b;
299+
expect(c.len == 0);
300+
}

0 commit comments

Comments
 (0)