From e9bac8be6b45434f107d2a0d8d4f8fd16de185c6 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 25 Feb 2020 18:35:35 +0100 Subject: [PATCH] ir: Fix array to slice conversion for zero-sized arrays Closes #3848 --- src/ir.cpp | 17 +++++++++++++---- test/stage1/behavior/slice.zig | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 77c7c74197..8a7976995c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -12588,13 +12588,22 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc { Error err; - if ((err = type_resolve(ira->codegen, array_ptr->value->type->data.pointer.child_type, - ResolveStatusAlignmentKnown))) - { + assert(array_ptr->value->type->id == ZigTypeIdPointer); + + if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) { return ira->codegen->invalid_inst_gen; } - wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, array_ptr->value->type)); + assert(array_ptr->value->type->data.pointer.child_type->id == ZigTypeIdArray); + + const size_t array_len = array_ptr->value->type->data.pointer.child_type->data.array.len; + + // A zero-sized array can always be casted irregardless of the destination + // alignment + if (array_len != 0) { + wanted_type = adjust_slice_align(ira->codegen, wanted_type, + get_ptr_align(ira->codegen, array_ptr->value->type)); + } if (instr_is_comptime(array_ptr)) { ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); diff --git a/test/stage1/behavior/slice.zig b/test/stage1/behavior/slice.zig index b985ec1f8e..c0fa723cfb 100644 --- a/test/stage1/behavior/slice.zig +++ b/test/stage1/behavior/slice.zig @@ -1,6 +1,7 @@ const std = @import("std"); const expect = std.testing.expect; const expectEqualSlices = std.testing.expectEqualSlices; +const expectEqual = std.testing.expectEqual; const mem = std.mem; const x = @intToPtr([*]i32, 0x1000)[0..0x500]; @@ -97,3 +98,20 @@ test "obtaining a null terminated slice" { comptime expect(@TypeOf(ptr2) == [:0]u8); comptime expect(@TypeOf(ptr2[0..2]) == []u8); } + +test "empty array to slice" { + const S = struct { + fn doTheTest() void { + const empty: []align(16) u8 = &[_]u8{}; + const align_1: []align(1) u8 = empty; + const align_4: []align(4) u8 = empty; + const align_16: []align(16) u8 = empty; + expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment); + expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment); + expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment); + } + }; + + S.doTheTest(); + comptime S.doTheTest(); +}