authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-20 17:28:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-20 17:29:06-07:00
log4d5e0a0434a69059f623e5c51862fb1a2c553abc
tree359645e37191ea162492f9814885d720421d52d2
parent7741aca96c8cc6df7e8c4bd10ada741d6a3ffb9d

Revert the last two commits in this branch

When the slice-by-length start position is runtime-known, it is likely protected by a runtime-known condition and therefore a compile error is less appropriate than a runtime panic check. This is demonstrated in the json code that was updated and then reverted in this commit. When #3806 is implemented, this decision can be reassessed. Revert "std: work around compiler unable to evaluate condition at compile time" Revert "frontend: comptime array slice-by-length OOB detection" This reverts commit 7741aca96c8cc6df7e8c4bd10ada741d6a3ffb9d. This reverts commit 2583b389eaf5f7aaa0eb79b51126506c1e172d15.

4 files changed, 28 insertions(+), 58 deletions(-)

lib/std/json/static.zig+17-13
......@@ -400,20 +400,24 @@ pub fn innerParse(
400400 @memcpy(r[i..][0..slice.len], slice);
401401 i += slice.len;
402402 },
403 inline .partial_string_escaped_1,
404 .partial_string_escaped_2,
405 .partial_string_escaped_3,
406 .partial_string_escaped_4,
407 => |arr| {
403 .partial_string_escaped_1 => |arr| {
408404 if (i + arr.len > r.len) return error.LengthMismatch;
409
410 // Implementing https://github.com/ziglang/zig/issues/3806
411 // would make this no longer needed because the
412 // above condition would become compile-time
413 // known.
414 if (arr.len > r.len) unreachable;
415
416 @memcpy(r[i..][0..arr.len], &arr);
405 @memcpy(r[i..][0..arr.len], arr[0..]);
406 i += arr.len;
407 },
408 .partial_string_escaped_2 => |arr| {
409 if (i + arr.len > r.len) return error.LengthMismatch;
410 @memcpy(r[i..][0..arr.len], arr[0..]);
411 i += arr.len;
412 },
413 .partial_string_escaped_3 => |arr| {
414 if (i + arr.len > r.len) return error.LengthMismatch;
415 @memcpy(r[i..][0..arr.len], arr[0..]);
416 i += arr.len;
417 },
418 .partial_string_escaped_4 => |arr| {
419 if (i + arr.len > r.len) return error.LengthMismatch;
420 @memcpy(r[i..][0..arr.len], arr[0..]);
417421 i += arr.len;
418422 },
419423 else => unreachable,
src/Sema.zig+9-28
......@@ -33285,34 +33285,15 @@ fn analyzeSlice(
3328533285 }
3328633286
3328733287 bounds_check: {
33288 const actual_len = l: {
33289 if (array_ty.zigTypeTag(mod) == .Array) {
33290 const len = array_ty.arrayLenIncludingSentinel(mod);
33291 // If the end is comptime-known, we can emit a
33292 // compile error if it would be out-of-bounds even
33293 // with a start value of 0.
33294 if (uncasted_end_opt != .none) {
33295 if (try sema.resolveDefinedValue(block, end_src, uncasted_end_opt)) |end_val| {
33296 const end_int = end_val.getUnsignedInt(mod).?;
33297 if (end_int > len) return sema.fail(
33298 block,
33299 end_src,
33300 "slice end index {d} exceeds array length of type '{}'",
33301 .{ end_int, array_ty.fmt(mod) },
33302 );
33303 }
33304 }
33305 break :l try mod.intRef(Type.usize, len);
33306 }
33307 if (slice_ty.isSlice(mod)) {
33308 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
33309 break :l if (slice_ty.sentinel(mod) == null)
33310 slice_len_inst
33311 else
33312 try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true);
33313 }
33314 break :bounds_check;
33315 };
33288 const actual_len = if (array_ty.zigTypeTag(mod) == .Array)
33289 try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))
33290 else if (slice_ty.isSlice(mod)) l: {
33291 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
33292 break :l if (slice_ty.sentinel(mod) == null)
33293 slice_len_inst
33294 else
33295 try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true);
33296 } else break :bounds_check;
3331633297
3331733298 const actual_end = if (slice_sentinel != null)
3331833299 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)
test/cases/compile_errors/out of bounds array slice by length.zig deleted-15
......@@ -1,15 +0,0 @@
1export fn b() void {
2 var buf: [5]u8 = undefined;
3 _ = buf[foo(6)..][0..10];
4 return error.TestFailed;
5}
6
7fn foo(a: u32) u32 {
8 return a;
9}
10
11// error
12// backend=stage2
13// target=native
14//
15// :3:26: error: slice end index 10 exceeds array length of type '[5]u8'
test/cases/safety/out of bounds array slice by length.zig +2-2
......@@ -2,14 +2,14 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
44 _ = stack_trace;
5 if (std.mem.eql(u8, message, "index out of bounds: index 9, len 5")) {
5 if (std.mem.eql(u8, message, "index out of bounds: index 16, len 5")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
99}
1010pub fn main() !void {
1111 var buf: [5]u8 = undefined;
12 _ = buf[foo(6)..][0..3];
12 _ = buf[foo(6)..][0..10];
1313 return error.TestFailed;
1414}
1515fn foo(a: u32) u32 {