authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-23 15:58:04+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-23 17:39:06+03:00
log581df942e1150dc2108bef1d91f0a77ba9c32e23
tree72403a12232cffbb1635a43109c587b663e14b7e
parent3de5c3b5038d03759d8f5521627fdbbcad28c795

Sema: correct sentinel check on implicit cast from array ptr

Closes #12938

2 files changed, 54 insertions(+), 13 deletions(-)

src/Sema.zig+31-13
......@@ -23014,9 +23014,37 @@ fn coerceExtra(
2301423014 const dest_is_mut = dest_info.mutable;
2301523015
2301623016 const dst_elem_type = dest_info.pointee_type;
23017 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src)) {
23017 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src);
23018 switch (elem_res) {
2301823019 .ok => {},
23019 else => break :src_array_ptr,
23020 else => {
23021 in_memory_result = .{ .ptr_child = .{
23022 .child = try elem_res.dupe(sema.arena),
23023 .actual = array_elem_type,
23024 .wanted = dst_elem_type,
23025 } };
23026 break :src_array_ptr;
23027 },
23028 }
23029
23030 if (dest_info.sentinel) |dest_sent| {
23031 if (array_ty.sentinel()) |inst_sent| {
23032 if (!dest_sent.eql(inst_sent, dst_elem_type, sema.mod)) {
23033 in_memory_result = .{ .ptr_sentinel = .{
23034 .actual = inst_sent,
23035 .wanted = dest_sent,
23036 .ty = dst_elem_type,
23037 } };
23038 break :src_array_ptr;
23039 }
23040 } else {
23041 in_memory_result = .{ .ptr_sentinel = .{
23042 .actual = Value.initTag(.unreachable_value),
23043 .wanted = dest_sent,
23044 .ty = dst_elem_type,
23045 } };
23046 break :src_array_ptr;
23047 }
2302023048 }
2302123049
2302223050 switch (dest_info.size) {
......@@ -23030,17 +23058,7 @@ fn coerceExtra(
2303023058 },
2303123059 .Many => {
2303223060 // *[N]T to [*]T
23033 // *[N:s]T to [*:s]T
23034 // *[N:s]T to [*]T
23035 if (dest_info.sentinel) |dst_sentinel| {
23036 if (array_ty.sentinel()) |src_sentinel| {
23037 if (src_sentinel.eql(dst_sentinel, dst_elem_type, sema.mod)) {
23038 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
23039 }
23040 }
23041 } else {
23042 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
23043 }
23061 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
2304423062 },
2304523063 .One => {},
2304623064 }
test/cases/compile_errors/implicit_array_ptr_cast_sentinel_mismatch.zig created+23
......@@ -0,0 +1,23 @@
1fn foo() [:0xff]const u8 {
2 return "bark";
3}
4fn bar() [:0]const u16 {
5 return "bark";
6}
7pub export fn entry() void {
8 _ = foo();
9}
10pub export fn entry1() void {
11 _ = bar();
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// :2:12: error: expected type '[:255]const u8', found '*const [4:0]u8'
19// :2:12: note: pointer sentinel '0' cannot cast into pointer sentinel '255'
20// :1:10: note: function return type declared here
21// :5:12: error: expected type '[:0]const u16', found '*const [4:0]u8'
22// :5:12: note: pointer type child 'u8' cannot cast into pointer type child 'u16'
23// :4:10: note: function return type declared here