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(...@@ -23014,9 +23014,37 @@ fn coerceExtra(
23014 const dest_is_mut = dest_info.mutable;23014 const dest_is_mut = dest_info.mutable;
2301523015
23016 const dst_elem_type = dest_info.pointee_type;23016 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) {
23018 .ok => {},23019 .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 }
23020 }23048 }
2302123049
23022 switch (dest_info.size) {23050 switch (dest_info.size) {
...@@ -23030,17 +23058,7 @@ fn coerceExtra(...@@ -23030,17 +23058,7 @@ fn coerceExtra(
23030 },23058 },
23031 .Many => {23059 .Many => {
23032 // *[N]T to [*]T23060 // *[N]T to [*]T
23033 // *[N:s]T to [*:s]T23061 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
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 }
23044 },23062 },
23045 .One => {},23063 .One => {},
23046 }23064 }
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