add compile error for incompatible pointer sentinels

This commit is contained in:
Andrew Kelley 2019-11-24 17:02:56 -05:00
parent 4018034708
commit c96d565166
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
2 changed files with 34 additions and 9 deletions

View File

@ -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: {

View File

@ -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 {