authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-24 17:02:56-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-24 17:02:56-05:00
logc96d565166a4e63487b43d6d50797b1037c9603c
treed639f53cd61bb26cb9a3c055e2162393d1a287ef
parent4018034708beea63086a34d361ffb400979a1189
signaturelock-open Commit is signed but in an unrecognized format.

add compile error for incompatible pointer sentinels


2 files changed, 34 insertions(+), 9 deletions(-)

src/ir.cpp+19-9
......@@ -183,6 +183,7 @@ struct ConstCastBadCV {
183183
184184struct ConstCastPtrSentinel {
185185 ZigType *wanted_type;
186 ZigType *actual_type;
186187};
187188
188189static 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
98989899 if (!ok_null_term_ptrs) {
98999900 result.id = ConstCastResultIdPtrSentinel;
99009901 result.data.bad_ptr_sentinel = allocate_nonzero<ConstCastPtrSentinel>(1);
9901 result.data.bad_ptr_sentinel->wanted_type = wanted_type;
9902 result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type;
9903 result.data.bad_ptr_sentinel->actual_type = actual_ptr_type;
99029904 return result;
99039905 }
99049906 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
1265312655 break;
1265412656 }
1265512657 case ConstCastResultIdPtrSentinel: {
12658 ZigType *actual_type = cast_result->data.bad_ptr_sentinel->actual_type;
1265612659 ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_type;
12657 Buf *msg = buf_sprintf("destination pointer requires a terminating '");
12658 render_const_value(ira->codegen, msg, wanted_type->data.pointer.sentinel);
12659 buf_appendf(msg, "' sentinel value");
12660 add_error_note(ira->codegen, parent_msg, source_node, msg);
12660 {
12661 Buf *txt_msg = buf_sprintf("destination pointer requires a terminating '");
12662 render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel);
12663 buf_appendf(txt_msg, "' sentinel value");
12664 if (actual_type->data.pointer.sentinel != nullptr) {
12665 buf_appendf(txt_msg, ", but source pointer has a terminating '");
12666 render_const_value(ira->codegen, txt_msg, actual_type->data.pointer.sentinel);
12667 buf_appendf(txt_msg, "' sentinel value");
12668 }
12669 add_error_note(ira->codegen, parent_msg, source_node, txt_msg);
12670 }
1266112671 break;
1266212672 }
1266312673 case ConstCastResultIdSentinelArrays: {
1266412674 ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type;
12665 Buf *msg = buf_sprintf("destination array requires a terminating '");
12666 render_const_value(ira->codegen, msg, wanted_type->data.pointer.sentinel);
12667 buf_appendf(msg, "' sentinel value");
12668 add_error_note(ira->codegen, parent_msg, source_node, msg);
12675 Buf *txt_msg = buf_sprintf("destination array requires a terminating '");
12676 render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel);
12677 buf_appendf(txt_msg, "' sentinel value");
12678 add_error_note(ira->codegen, parent_msg, source_node, txt_msg);
1266912679 break;
1267012680 }
1267112681 case ConstCastResultIdCV: {
test/compile_errors.zig+15
......@@ -2,6 +2,21 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "incompatible pointer sentinels",
7 \\export fn entry1(ptr: [*:255]u8) [*:0]u8 {
8 \\ return ptr;
9 \\}
10 \\export fn entry2(ptr: [*]u8) [*:0]u8 {
11 \\ return ptr;
12 \\}
13 ,
14 "tmp.zig:2:5: error: expected type '[*:0]u8', found '[*:255]u8'",
15 "tmp.zig:2:5: note: destination pointer requires a terminating '0' sentinel value, but source pointer has a terminating '255' sentinel value",
16 "tmp.zig:5:5: error: expected type '[*:0]u8', found '[*]u8'",
17 "tmp.zig:5:5: note: destination pointer requires a terminating '0' sentinel value",
18 );
19
520 cases.add(
621 "regression test #2980: base type u32 is not type checked properly when assigning a value within a struct",
722 \\const Foo = struct {