Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sentinel-terminated pointers #3728

Merged
merged 25 commits into from
Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1aa978f
implement null terminated pointers
andrewrk Nov 14, 2019
21f344b
add null terminated pointers and arrays to self-hosted
andrewrk Nov 18, 2019
47f06be
string literals are now null terminated
andrewrk Nov 20, 2019
cf2fe25
better error message when null termination does not match
andrewrk Nov 20, 2019
fd6020c
update tests, better error messages, update self-hosted tokenizer
andrewrk Nov 20, 2019
6b623b5
update docs for null terminated stuff
andrewrk Nov 20, 2019
7597735
update the stage1 implementation to the new proposal
andrewrk Nov 23, 2019
f25182f
structs can have fields with type `var`
andrewrk Nov 23, 2019
00878a1
zig fmt: support sentinel-terminated pointer syntax
andrewrk Nov 24, 2019
2dd20aa
langref: update for sentinel-terminated types
andrewrk Nov 24, 2019
4c7b525
all tests passing
andrewrk Nov 24, 2019
44b1dc6
add type coercion: [:x]T to [*:x]T
andrewrk Nov 24, 2019
f7574f4
add test for struct with var field
andrewrk Nov 24, 2019
09ec720
fix comptime `@ptrCast` of pointers to arrays
andrewrk Nov 24, 2019
4018034
add test cases for arbitrary pointer sentinels
andrewrk Nov 24, 2019
c96d565
add compile error for incompatible pointer sentinels
andrewrk Nov 24, 2019
217a509
fix compile error regressions
andrewrk Nov 24, 2019
7eb5acd
fix casting `[N:x]T` to `[N]T` memcpying too many bytes
andrewrk Nov 24, 2019
ce96323
update cli test
andrewrk Nov 25, 2019
b9f88c3
fix compile errors for array sentinels mismatching
andrewrk Nov 25, 2019
34b1ebe
Merge remote-tracking branch 'origin/master' into null-terminated-poi…
andrewrk Nov 25, 2019
15d415e
make std.mem.toSlice use null terminated pointers
andrewrk Nov 25, 2019
29e438f
more sentinel-terminated pointers std lib integration
andrewrk Nov 25, 2019
d2cb740
add missing null terminator in windows file path helper function
andrewrk Nov 25, 2019
3217264
fix freebsd regression
andrewrk Nov 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions src/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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: {
Expand Down
15 changes: 15 additions & 0 deletions test/compile_errors.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down