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(...@@ -400,20 +400,24 @@ pub fn innerParse(
400 @memcpy(r[i..][0..slice.len], slice);400 @memcpy(r[i..][0..slice.len], slice);
401 i += slice.len;401 i += slice.len;
402 },402 },
403 inline .partial_string_escaped_1,403 .partial_string_escaped_1 => |arr| {
404 .partial_string_escaped_2,
405 .partial_string_escaped_3,
406 .partial_string_escaped_4,
407 => |arr| {
408 if (i + arr.len > r.len) return error.LengthMismatch;404 if (i + arr.len > r.len) return error.LengthMismatch;
409405 @memcpy(r[i..][0..arr.len], arr[0..]);
410 // Implementing https://github.com/ziglang/zig/issues/3806406 i += arr.len;
411 // would make this no longer needed because the407 },
412 // above condition would become compile-time408 .partial_string_escaped_2 => |arr| {
413 // known.409 if (i + arr.len > r.len) return error.LengthMismatch;
414 if (arr.len > r.len) unreachable;410 @memcpy(r[i..][0..arr.len], arr[0..]);
415411 i += arr.len;
416 @memcpy(r[i..][0..arr.len], &arr);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..]);
417 i += arr.len;421 i += arr.len;
418 },422 },
419 else => unreachable,423 else => unreachable,
src/Sema.zig+9-28
...@@ -33285,34 +33285,15 @@ fn analyzeSlice(...@@ -33285,34 +33285,15 @@ fn analyzeSlice(
33285 }33285 }
3328633286
33287 bounds_check: {33287 bounds_check: {
33288 const actual_len = l: {33288 const actual_len = if (array_ty.zigTypeTag(mod) == .Array)
33289 if (array_ty.zigTypeTag(mod) == .Array) {33289 try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))
33290 const len = array_ty.arrayLenIncludingSentinel(mod);33290 else if (slice_ty.isSlice(mod)) l: {
33291 // If the end is comptime-known, we can emit a33291 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
33292 // compile error if it would be out-of-bounds even33292 break :l if (slice_ty.sentinel(mod) == null)
33293 // with a start value of 0.33293 slice_len_inst
33294 if (uncasted_end_opt != .none) {33294 else
33295 if (try sema.resolveDefinedValue(block, end_src, uncasted_end_opt)) |end_val| {33295 try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true);
33296 const end_int = end_val.getUnsignedInt(mod).?;33296 } else break :bounds_check;
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 };
3331633297
33317 const actual_end = if (slice_sentinel != null)33298 const actual_end = if (slice_sentinel != null)
33318 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)33299 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");...@@ -2,14 +2,14 @@ const std = @import("std");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
4 _ = stack_trace;4 _ = 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")) {
6 std.process.exit(0);6 std.process.exit(0);
7 }7 }
8 std.process.exit(1);8 std.process.exit(1);
9}9}
10pub fn main() !void {10pub fn main() !void {
11 var buf: [5]u8 = undefined;11 var buf: [5]u8 = undefined;
12 _ = buf[foo(6)..][0..3];12 _ = buf[foo(6)..][0..10];
13 return error.TestFailed;13 return error.TestFailed;
14}14}
15fn foo(a: u32) u32 {15fn foo(a: u32) u32 {