Commit 4d5e0a0434

Andrew Kelley <andrew@ziglang.org>
2024-03-21 01:28:51
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.
1 parent 7741aca
Changed files (4)
lib/std/json/static.zig
@@ -400,20 +400,24 @@ pub fn innerParse(
                                 @memcpy(r[i..][0..slice.len], slice);
                                 i += slice.len;
                             },
-                            inline .partial_string_escaped_1,
-                            .partial_string_escaped_2,
-                            .partial_string_escaped_3,
-                            .partial_string_escaped_4,
-                            => |arr| {
+                            .partial_string_escaped_1 => |arr| {
                                 if (i + arr.len > r.len) return error.LengthMismatch;
-
-                                // Implementing https://github.com/ziglang/zig/issues/3806
-                                // would make this no longer needed because the
-                                // above condition would become compile-time
-                                // known.
-                                if (arr.len > r.len) unreachable;
-
-                                @memcpy(r[i..][0..arr.len], &arr);
+                                @memcpy(r[i..][0..arr.len], arr[0..]);
+                                i += arr.len;
+                            },
+                            .partial_string_escaped_2 => |arr| {
+                                if (i + arr.len > r.len) return error.LengthMismatch;
+                                @memcpy(r[i..][0..arr.len], arr[0..]);
+                                i += arr.len;
+                            },
+                            .partial_string_escaped_3 => |arr| {
+                                if (i + arr.len > r.len) return error.LengthMismatch;
+                                @memcpy(r[i..][0..arr.len], arr[0..]);
+                                i += arr.len;
+                            },
+                            .partial_string_escaped_4 => |arr| {
+                                if (i + arr.len > r.len) return error.LengthMismatch;
+                                @memcpy(r[i..][0..arr.len], arr[0..]);
                                 i += arr.len;
                             },
                             else => unreachable,
src/Sema.zig
@@ -33285,34 +33285,15 @@ fn analyzeSlice(
                 }
 
                 bounds_check: {
-                    const actual_len = l: {
-                        if (array_ty.zigTypeTag(mod) == .Array) {
-                            const len = array_ty.arrayLenIncludingSentinel(mod);
-                            // If the end is comptime-known, we can emit a
-                            // compile error if it would be out-of-bounds even
-                            // with a start value of 0.
-                            if (uncasted_end_opt != .none) {
-                                if (try sema.resolveDefinedValue(block, end_src, uncasted_end_opt)) |end_val| {
-                                    const end_int = end_val.getUnsignedInt(mod).?;
-                                    if (end_int > len) return sema.fail(
-                                        block,
-                                        end_src,
-                                        "slice end index {d} exceeds array length of type '{}'",
-                                        .{ end_int, array_ty.fmt(mod) },
-                                    );
-                                }
-                            }
-                            break :l try mod.intRef(Type.usize, len);
-                        }
-                        if (slice_ty.isSlice(mod)) {
-                            const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
-                            break :l if (slice_ty.sentinel(mod) == null)
-                                slice_len_inst
-                            else
-                                try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true);
-                        }
-                        break :bounds_check;
-                    };
+                    const actual_len = if (array_ty.zigTypeTag(mod) == .Array)
+                        try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod))
+                    else if (slice_ty.isSlice(mod)) l: {
+                        const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
+                        break :l if (slice_ty.sentinel(mod) == null)
+                            slice_len_inst
+                        else
+                            try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true);
+                    } else break :bounds_check;
 
                     const actual_end = if (slice_sentinel != null)
                         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
@@ -1,15 +0,0 @@
-export fn b() void {
-    var buf: [5]u8 = undefined;
-    _ = buf[foo(6)..][0..10];
-    return error.TestFailed;
-}
-
-fn foo(a: u32) u32 {
-    return a;
-}
-
-// error
-// backend=stage2
-// target=native
-//
-// :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,14 +2,14 @@ const std = @import("std");
 
 pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
     _ = stack_trace;
-    if (std.mem.eql(u8, message, "index out of bounds: index 9, len 5")) {
+    if (std.mem.eql(u8, message, "index out of bounds: index 16, len 5")) {
         std.process.exit(0);
     }
     std.process.exit(1);
 }
 pub fn main() !void {
     var buf: [5]u8 = undefined;
-    _ = buf[foo(6)..][0..3];
+    _ = buf[foo(6)..][0..10];
     return error.TestFailed;
 }
 fn foo(a: u32) u32 {