authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-25 18:35:35+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-25 17:40:01-05:00
loge9bac8be6b45434f107d2a0d8d4f8fd16de185c6
tree604d76d1fb6d576d017e92a7cf04474e878f371e
parent55ea855e2cefe8dcdb5fab9be66aa6ca3acd0370

ir: Fix array to slice conversion for zero-sized arrays

Closes #3848

2 files changed, 31 insertions(+), 4 deletions(-)

src/ir.cpp+13-4
...@@ -12588,13 +12588,22 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc...@@ -12588,13 +12588,22 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc
12588{12588{
12589 Error err;12589 Error err;
1259012590
12591 if ((err = type_resolve(ira->codegen, array_ptr->value->type->data.pointer.child_type,12591 assert(array_ptr->value->type->id == ZigTypeIdPointer);
12592 ResolveStatusAlignmentKnown)))12592
12593 {12593 if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) {
12594 return ira->codegen->invalid_inst_gen;12594 return ira->codegen->invalid_inst_gen;
12595 }12595 }
1259612596
12597 wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, array_ptr->value->type));12597 assert(array_ptr->value->type->data.pointer.child_type->id == ZigTypeIdArray);
12598
12599 const size_t array_len = array_ptr->value->type->data.pointer.child_type->data.array.len;
12600
12601 // A zero-sized array can always be casted irregardless of the destination
12602 // alignment
12603 if (array_len != 0) {
12604 wanted_type = adjust_slice_align(ira->codegen, wanted_type,
12605 get_ptr_align(ira->codegen, array_ptr->value->type));
12606 }
1259812607
12599 if (instr_is_comptime(array_ptr)) {12608 if (instr_is_comptime(array_ptr)) {
12600 ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);12609 ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
test/stage1/behavior/slice.zig+18
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectEqualSlices = std.testing.expectEqualSlices;3const expectEqualSlices = std.testing.expectEqualSlices;
4const expectEqual = std.testing.expectEqual;
4const mem = std.mem;5const mem = std.mem;
56
6const x = @intToPtr([*]i32, 0x1000)[0..0x500];7const x = @intToPtr([*]i32, 0x1000)[0..0x500];
...@@ -97,3 +98,20 @@ test "obtaining a null terminated slice" {...@@ -97,3 +98,20 @@ test "obtaining a null terminated slice" {
97 comptime expect(@TypeOf(ptr2) == [:0]u8);98 comptime expect(@TypeOf(ptr2) == [:0]u8);
98 comptime expect(@TypeOf(ptr2[0..2]) == []u8);99 comptime expect(@TypeOf(ptr2[0..2]) == []u8);
99}100}
101
102test "empty array to slice" {
103 const S = struct {
104 fn doTheTest() void {
105 const empty: []align(16) u8 = &[_]u8{};
106 const align_1: []align(1) u8 = empty;
107 const align_4: []align(4) u8 = empty;
108 const align_16: []align(16) u8 = empty;
109 expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment);
110 expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment);
111 expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment);
112 }
113 };
114
115 S.doTheTest();
116 comptime S.doTheTest();
117}