mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
add compile error for incompatible pointer sentinels
This commit is contained in:
parent
4018034708
commit
c96d565166
2 changed files with 34 additions and 9 deletions
28
src/ir.cpp
28
src/ir.cpp
|
|
@ -183,6 +183,7 @@ struct ConstCastBadCV {
|
||||||
|
|
||||||
struct ConstCastPtrSentinel {
|
struct ConstCastPtrSentinel {
|
||||||
ZigType *wanted_type;
|
ZigType *wanted_type;
|
||||||
|
ZigType *actual_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
|
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) {
|
if (!ok_null_term_ptrs) {
|
||||||
result.id = ConstCastResultIdPtrSentinel;
|
result.id = ConstCastResultIdPtrSentinel;
|
||||||
result.data.bad_ptr_sentinel = allocate_nonzero<ConstCastPtrSentinel>(1);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case ConstCastResultIdPtrSentinel: {
|
case ConstCastResultIdPtrSentinel: {
|
||||||
|
ZigType *actual_type = cast_result->data.bad_ptr_sentinel->actual_type;
|
||||||
ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_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 *txt_msg = buf_sprintf("destination pointer requires a terminating '");
|
||||||
buf_appendf(msg, "' sentinel value");
|
render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel);
|
||||||
add_error_note(ira->codegen, parent_msg, source_node, msg);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case ConstCastResultIdSentinelArrays: {
|
case ConstCastResultIdSentinelArrays: {
|
||||||
ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type;
|
ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type;
|
||||||
Buf *msg = buf_sprintf("destination array requires a terminating '");
|
Buf *txt_msg = buf_sprintf("destination array requires a terminating '");
|
||||||
render_const_value(ira->codegen, msg, wanted_type->data.pointer.sentinel);
|
render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel);
|
||||||
buf_appendf(msg, "' sentinel value");
|
buf_appendf(txt_msg, "' sentinel value");
|
||||||
add_error_note(ira->codegen, parent_msg, source_node, msg);
|
add_error_note(ira->codegen, parent_msg, source_node, txt_msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConstCastResultIdCV: {
|
case ConstCastResultIdCV: {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,21 @@ const tests = @import("tests.zig");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
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(
|
cases.add(
|
||||||
"regression test #2980: base type u32 is not type checked properly when assigning a value within a struct",
|
"regression test #2980: base type u32 is not type checked properly when assigning a value within a struct",
|
||||||
\\const Foo = struct {
|
\\const Foo = struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue