| author | |
| committer | |
| log | 6695fa4f326e807256b9afc6321e63a90b08e1ba |
| tree | e5a6d7aa12dce2d9ac468e5c15431058f1578699 |
| parent | 212e2354b8ab631995b0c25f7cf1d9a3e01fac57 |
The code assumed that every ?T had a pointer child type T, add some more
checks to make sure the type is effectively a pointer.
Closes #47892 files changed, 15 insertions(+), 4 deletions(-)
src/ir.cpp+2-4| ... | ... | @@ -11454,10 +11454,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 11454 | 11454 | bool actual_allows_zero = ptr_allows_addr_zero(actual_type); |
| 11455 | 11455 | bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC; |
| 11456 | 11456 | bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC; |
| 11457 | bool wanted_opt_or_ptr = wanted_ptr_type != nullptr && | |
| 11458 | (wanted_type->id == ZigTypeIdPointer || wanted_type->id == ZigTypeIdOptional); | |
| 11459 | bool actual_opt_or_ptr = actual_ptr_type != nullptr && | |
| 11460 | (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); | |
| 11457 | bool wanted_opt_or_ptr = wanted_ptr_type != nullptr && wanted_ptr_type->id == ZigTypeIdPointer; | |
| 11458 | bool actual_opt_or_ptr = actual_ptr_type != nullptr && actual_ptr_type->id == ZigTypeIdPointer; | |
| 11461 | 11459 | if (wanted_opt_or_ptr && actual_opt_or_ptr) { |
| 11462 | 11460 | bool ok_null_term_ptrs = |
| 11463 | 11461 | wanted_ptr_type->data.pointer.sentinel == nullptr || |
test/compile_errors.zig+13| ... | ... | @@ -2,6 +2,19 @@ const tests = @import("tests.zig"); |
| 2 | 2 | const std = @import("std"); |
| 3 | 3 | |
| 4 | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.addTest("cast between ?T where T is not a pointer", | |
| 6 | \\pub const fnty1 = ?fn (i8) void; | |
| 7 | \\pub const fnty2 = ?fn (u64) void; | |
| 8 | \\export fn entry() void { | |
| 9 | \\ var a: fnty1 = undefined; | |
| 10 | \\ var b: fnty2 = undefined; | |
| 11 | \\ a = b; | |
| 12 | \\} | |
| 13 | , &[_][]const u8{ | |
| 14 | "tmp.zig:6:9: error: expected type '?fn(i8) void', found '?fn(u64) void'", | |
| 15 | "tmp.zig:6:9: note: optional type child 'fn(u64) void' cannot cast into optional type child 'fn(i8) void'", | |
| 16 | }); | |
| 17 | ||
| 5 | 18 | cases.addTest("unused variable error on errdefer", |
| 6 | 19 | \\fn foo() !void { |
| 7 | 20 | \\ errdefer |a| unreachable; |