Commit c96d565166
Changed files (2)
src
src/ir.cpp
@@ -183,6 +183,7 @@ struct ConstCastBadCV {
struct ConstCastPtrSentinel {
ZigType *wanted_type;
+ ZigType *actual_type;
};
static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
@@ -9898,7 +9899,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
if (!ok_null_term_ptrs) {
result.id = ConstCastResultIdPtrSentinel;
result.data.bad_ptr_sentinel = allocate_nonzero<ConstCastPtrSentinel>(1);
- result.data.bad_ptr_sentinel->wanted_type = wanted_type;
+ result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type;
+ result.data.bad_ptr_sentinel->actual_type = actual_ptr_type;
return result;
}
bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len;
@@ -12653,19 +12655,27 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
break;
}
case ConstCastResultIdPtrSentinel: {
+ ZigType *actual_type = cast_result->data.bad_ptr_sentinel->actual_type;
ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_type;
- Buf *msg = buf_sprintf("destination pointer requires a terminating '");
- render_const_value(ira->codegen, msg, wanted_type->data.pointer.sentinel);
- buf_appendf(msg, "' sentinel value");
- add_error_note(ira->codegen, parent_msg, source_node, msg);
+ {
+ Buf *txt_msg = buf_sprintf("destination pointer requires a terminating '");
+ render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel);
+ buf_appendf(txt_msg, "' sentinel value");
+ if (actual_type->data.pointer.sentinel != nullptr) {
+ buf_appendf(txt_msg, ", but source pointer has a terminating '");
+ render_const_value(ira->codegen, txt_msg, actual_type->data.pointer.sentinel);
+ buf_appendf(txt_msg, "' sentinel value");
+ }
+ add_error_note(ira->codegen, parent_msg, source_node, txt_msg);
+ }
break;
}
case ConstCastResultIdSentinelArrays: {
ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type;
- Buf *msg = buf_sprintf("destination array requires a terminating '");
- render_const_value(ira->codegen, msg, wanted_type->data.pointer.sentinel);
- buf_appendf(msg, "' sentinel value");
- add_error_note(ira->codegen, parent_msg, source_node, msg);
+ Buf *txt_msg = buf_sprintf("destination array requires a terminating '");
+ render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel);
+ buf_appendf(txt_msg, "' sentinel value");
+ add_error_note(ira->codegen, parent_msg, source_node, txt_msg);
break;
}
case ConstCastResultIdCV: {
test/compile_errors.zig
@@ -2,6 +2,21 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "incompatible pointer sentinels",
+ \\export fn entry1(ptr: [*:255]u8) [*:0]u8 {
+ \\ return ptr;
+ \\}
+ \\export fn entry2(ptr: [*]u8) [*:0]u8 {
+ \\ return ptr;
+ \\}
+ ,
+ "tmp.zig:2:5: error: expected type '[*:0]u8', found '[*:255]u8'",
+ "tmp.zig:2:5: note: destination pointer requires a terminating '0' sentinel value, but source pointer has a terminating '255' sentinel value",
+ "tmp.zig:5:5: error: expected type '[*:0]u8', found '[*]u8'",
+ "tmp.zig:5:5: note: destination pointer requires a terminating '0' sentinel value",
+ );
+
cases.add(
"regression test #2980: base type u32 is not type checked properly when assigning a value within a struct",
\\const Foo = struct {