mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Sema: disallow slicing many-item pointer with different sentinel
This change prevents adding or changing the sentinel in the type of a many-item pointer via the slicing syntax `ptr[a.. :S]`.
This commit is contained in:
parent
bce6a7c215
commit
19fc5f4fb2
32
src/Sema.zig
32
src/Sema.zig
@ -31876,6 +31876,38 @@ fn analyzeSlice(
|
|||||||
break :e try sema.coerce(block, .usize, uncasted_end, end_src);
|
break :e try sema.coerce(block, .usize, uncasted_end, end_src);
|
||||||
} else break :e try sema.coerce(block, .usize, uncasted_end_opt, end_src);
|
} else break :e try sema.coerce(block, .usize, uncasted_end_opt, end_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// when slicing a many-item pointer, if a sentinel `S` is provided as in `ptr[a.. :S]`, it
|
||||||
|
// must match the sentinel of `@TypeOf(ptr)`.
|
||||||
|
sentinel_check: {
|
||||||
|
if (sentinel_opt == .none) break :sentinel_check;
|
||||||
|
const provided = provided: {
|
||||||
|
const casted = try sema.coerce(block, elem_ty, sentinel_opt, sentinel_src);
|
||||||
|
try checkSentinelType(sema, block, sentinel_src, elem_ty);
|
||||||
|
break :provided try sema.resolveConstDefinedValue(
|
||||||
|
block,
|
||||||
|
sentinel_src,
|
||||||
|
casted,
|
||||||
|
.{ .simple = .slice_sentinel },
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ptr_sentinel) |current| {
|
||||||
|
if (provided.toIntern() == current.toIntern()) break :sentinel_check;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sema.failWithOwnedErrorMsg(block, msg: {
|
||||||
|
const msg = try sema.errMsg(sentinel_src, "sentinel-terminated slicing of many-item pointer must match existing sentinel", .{});
|
||||||
|
errdefer msg.destroy(sema.gpa);
|
||||||
|
if (ptr_sentinel) |current| {
|
||||||
|
try sema.errNote(sentinel_src, msg, "expected sentinel '{f}', found '{f}'", .{ current.fmtValue(pt), provided.fmtValue(pt) });
|
||||||
|
} else {
|
||||||
|
try sema.errNote(ptr_src, msg, "type '{f}' does not have a sentinel", .{slice_ty.fmt(pt)});
|
||||||
|
}
|
||||||
|
try sema.errNote(src, msg, "use @ptrCast to cast pointer sentinel", .{});
|
||||||
|
break :msg msg;
|
||||||
|
});
|
||||||
|
}
|
||||||
return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
|
return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -628,9 +628,6 @@ test "slice syntax resulting in pointer-to-array" {
|
|||||||
comptime assert(@TypeOf(ptr[1..][0..2]) == *[2]u8);
|
comptime assert(@TypeOf(ptr[1..][0..2]) == *[2]u8);
|
||||||
comptime assert(@TypeOf(ptr[1..][0..4]) == *[4]u8);
|
comptime assert(@TypeOf(ptr[1..][0..4]) == *[4]u8);
|
||||||
comptime assert(@TypeOf(ptr[1..][0..2 :4]) == *[2:4]u8);
|
comptime assert(@TypeOf(ptr[1..][0..2 :4]) == *[2:4]u8);
|
||||||
comptime assert(@TypeOf(ptr[1.. :0][0..2]) == *[2]u8);
|
|
||||||
comptime assert(@TypeOf(ptr[1.. :0][0..4]) == *[4]u8);
|
|
||||||
comptime assert(@TypeOf(ptr[1.. :0][0..2 :4]) == *[2:4]u8);
|
|
||||||
|
|
||||||
var ptr_z: [*:0]u8 = &array;
|
var ptr_z: [*:0]u8 = &array;
|
||||||
comptime assert(@TypeOf(ptr_z[1..][0..2]) == *[2]u8);
|
comptime assert(@TypeOf(ptr_z[1..][0..2]) == *[2]u8);
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
comptime {
|
||||||
|
var ptr: [*]const u8 = undefined;
|
||||||
|
_ = ptr[0.. :0];
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var ptrz: [*:0]const u8 = undefined;
|
||||||
|
_ = ptrz[0.. :1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
//
|
||||||
|
// :3:18: error: sentinel-terminated slicing of many-item pointer must match existing sentinel
|
||||||
|
// :3:9: note: type '[*]const u8' does not have a sentinel
|
||||||
|
// :3:12: note: use @ptrCast to cast pointer sentinel
|
||||||
|
// :8:19: error: sentinel-terminated slicing of many-item pointer must match existing sentinel
|
||||||
|
// :8:19: note: expected sentinel '0', found '1'
|
||||||
|
// :8:13: note: use @ptrCast to cast pointer sentinel
|
||||||
Loading…
x
Reference in New Issue
Block a user