add compile error for incompatible pointer sentinels
This commit is contained in:
parent
4018034708
commit
c96d565166
28
src/ir.cpp
28
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: {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue
Block a user