Skip to content

Commit

Permalink
Revert the last two commits in this branch
Browse files Browse the repository at this point in the history
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 7741aca.
This reverts commit 2583b38.
  • Loading branch information
andrewrk committed Mar 21, 2024
1 parent 7741aca commit 4d5e0a0
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 58 deletions.
30 changes: 17 additions & 13 deletions lib/std/json/static.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
37 changes: 9 additions & 28 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 0 additions & 15 deletions test/cases/compile_errors/out of bounds array slice by length.zig

This file was deleted.

4 changes: 2 additions & 2 deletions test/cases/safety/out of bounds array slice by length.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 4d5e0a0

Please sign in to comment.