From 45e961772050191ce94becc53dcb86971a5804ab Mon Sep 17 00:00:00 2001 From: mlugg Date: Thu, 15 Jun 2023 01:04:22 +0100 Subject: [PATCH 1/2] Sema: don't assume slice value is interned when loading from comptime pointer Resolves: #16030 --- src/Sema.zig | 2 +- test/behavior/slice.zig | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index f703c6154c..c4dba205a3 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -29265,7 +29265,7 @@ fn beginComptimePtrLoad( }, Value.slice_len_index => TypedValue{ .ty = Type.usize, - .val = mod.intern_pool.indexToKey(tv.val.toIntern()).ptr.len.toValue(), + .val = mod.intern_pool.indexToKey(try tv.val.intern(tv.ty, mod)).ptr.len.toValue(), }, else => unreachable, }; diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index fb9d1e047a..79990feba4 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -869,3 +869,20 @@ test "write through pointer to optional slice arg" { try S.bar(&foo); try expectEqualStrings(foo.?, "ok"); } + +test "modify slice length at comptime" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; + + const arr: [2]u8 = .{ 10, 20 }; + comptime var s: []const u8 = arr[0..0]; + s.len += 1; + const a = s; + s.len += 1; + const b = s; + + try expectEqualSlices(u8, &.{10}, a); + try expectEqualSlices(u8, &.{ 10, 20 }, b); +} From 57f6e6729f74bc7f43848aff6cd52e89465cc49e Mon Sep 17 00:00:00 2001 From: mlugg Date: Thu, 15 Jun 2023 01:19:17 +0100 Subject: [PATCH 2/2] Sema: allow empty end index in zirSliceSentinel This fixes a regression, and enables some related behavior tests which were accidentally disabled. --- src/Sema.zig | 2 +- test/behavior/slice.zig | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index c4dba205a3..4b5c0c6d8d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -10069,7 +10069,7 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data; const array_ptr = try sema.resolveInst(extra.lhs); const start = try sema.resolveInst(extra.start); - const end = try sema.resolveInst(extra.end); + const end: Air.Inst.Ref = if (extra.end == .none) .none else try sema.resolveInst(extra.end); const sentinel = try sema.resolveInst(extra.sentinel); const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node }; const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node }; diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 79990feba4..ae5fbf0951 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -378,12 +378,16 @@ test "slice syntax resulting in pointer-to-array" { try testPointer0(); try testPointerAlign(); try testSlice(); + try testSliceZ(); try testSliceOpt(); try testSliceAlign(); + try testConcatStrLiterals(); try testSliceLength(); try testSliceLengthZ(); try testArrayLength(); try testArrayLengthZ(); + try testMultiPointer(); + try testMultiPointerLengthZ(); } fn testArray() !void { @@ -469,8 +473,12 @@ test "slice syntax resulting in pointer-to-array" { var array = [5:0]u8{ 1, 2, 3, 4, 5 }; var slice: [:0]u8 = &array; try comptime expect(@TypeOf(slice[1..3]) == *[2]u8); - try comptime expect(@TypeOf(slice[1..]) == [:0]u8); try comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8); + if (@inComptime()) { + try comptime expect(@TypeOf(slice[1..]) == *[4:0]u8); + } else { + try comptime expect(@TypeOf(slice[1..]) == [:0]u8); + } } fn testSliceOpt() !void { @@ -491,8 +499,8 @@ test "slice syntax resulting in pointer-to-array" { } fn testConcatStrLiterals() !void { - try expectEqualSlices("a"[0..] ++ "b"[0..], "ab"); - try expectEqualSlices("a"[0.. :0] ++ "b"[0.. :0], "ab"); + try expectEqualSlices(u8, "ab", "a"[0..] ++ "b"[0..]); + try expectEqualSlices(u8, "ab", "a"[0.. :0] ++ "b"[0.. :0]); } fn testSliceLength() !void { @@ -541,18 +549,18 @@ test "slice syntax resulting in pointer-to-array" { var array = [5:0]u8{ 1, 2, 3, 4, 5 }; var ptr: [*]u8 = &array; try comptime expect(@TypeOf(ptr[1..][0..2]) == *[2]u8); - try comptime expect(@TypeOf(ptr[1..][0..4]) == *[4:0]u8); + try comptime expect(@TypeOf(ptr[1..][0..4]) == *[4]u8); try comptime expect(@TypeOf(ptr[1..][0..2 :4]) == *[2:4]u8); try comptime expect(@TypeOf(ptr[1.. :0][0..2]) == *[2]u8); - try comptime expect(@TypeOf(ptr[1.. :0][0..4]) == *[4:0]u8); + try comptime expect(@TypeOf(ptr[1.. :0][0..4]) == *[4]u8); try comptime expect(@TypeOf(ptr[1.. :0][0..2 :4]) == *[2:4]u8); var ptr_z: [*:0]u8 = &array; try comptime expect(@TypeOf(ptr_z[1..][0..2]) == *[2]u8); - try comptime expect(@TypeOf(ptr_z[1..][0..4]) == *[4:0]u8); + try comptime expect(@TypeOf(ptr_z[1..][0..4]) == *[4]u8); try comptime expect(@TypeOf(ptr_z[1..][0..2 :4]) == *[2:4]u8); try comptime expect(@TypeOf(ptr_z[1.. :0][0..2]) == *[2]u8); - try comptime expect(@TypeOf(ptr_z[1.. :0][0..4]) == *[4:0]u8); + try comptime expect(@TypeOf(ptr_z[1.. :0][0..4]) == *[4]u8); try comptime expect(@TypeOf(ptr_z[1.. :0][0..2 :4]) == *[2:4]u8); } };