authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-14 12:28:50-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-14 12:28:50-05:00
loge03c770145b5dc7b428d53b3cac97c2733fb84d8
treec787bf811386c8ea3cc0f317350c3c77815c26cf
parent59de24817e8538434f35a20a401f40c2f0231a9a
signature Commit is signed but in an unrecognized format.

compile error tests for implicit C pointer casting

See #1059

2 files changed, 55 insertions(+), 20 deletions(-)

src/ir.cpp+18-20
......@@ -8683,16 +8683,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
86838683 bool actual_opt_or_ptr = actual_ptr_type != nullptr &&
86848684 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);
86858685 if (wanted_opt_or_ptr && actual_opt_or_ptr) {
8686 bool ok_allows_zero = (wanted_allows_zero &&
8687 (actual_allows_zero || wanted_ptr_type->data.pointer.is_const)) ||
8688 (!wanted_allows_zero && !actual_allows_zero);
8689 if (!ok_allows_zero) {
8690 result.id = ConstCastResultIdBadAllowsZero;
8691 result.data.bad_allows_zero = allocate_nonzero<ConstCastBadAllowsZero>(1);
8692 result.data.bad_allows_zero->wanted_type = wanted_type;
8693 result.data.bad_allows_zero->actual_type = actual_type;
8694 return result;
8695 }
86968686 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
86978687 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
86988688 if (child.id == ConstCastResultIdInvalid)
......@@ -8705,6 +8695,16 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
87058695 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
87068696 return result;
87078697 }
8698 bool ok_allows_zero = (wanted_allows_zero &&
8699 (actual_allows_zero || wanted_ptr_type->data.pointer.is_const)) ||
8700 (!wanted_allows_zero && !actual_allows_zero);
8701 if (!ok_allows_zero) {
8702 result.id = ConstCastResultIdBadAllowsZero;
8703 result.data.bad_allows_zero = allocate_nonzero<ConstCastBadAllowsZero>(1);
8704 result.data.bad_allows_zero->wanted_type = wanted_type;
8705 result.data.bad_allows_zero->actual_type = actual_type;
8706 return result;
8707 }
87088708 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
87098709 result.id = ConstCastResultIdInvalid;
87108710 return result;
......@@ -10846,22 +10846,20 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
1084610846 break;
1084710847 }
1084810848 case ConstCastResultIdBadAllowsZero: {
10849 bool wanted_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->wanted_type);
10850 bool actual_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->actual_type);
10851 ZigType *wanted_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->wanted_type);
10852 ZigType *actual_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->actual_type);
10853 ZigType *wanted_elem_type = wanted_ptr_type->data.pointer.child_type;
10854 ZigType *actual_elem_type = actual_ptr_type->data.pointer.child_type;
10849 ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type;
10850 ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type;
10851 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type);
10852 bool actual_allows_zero = ptr_allows_addr_zero(actual_type);
1085510853 if (actual_allows_zero && !wanted_allows_zero) {
1085610854 add_error_note(ira->codegen, parent_msg, source_node,
1085710855 buf_sprintf("'%s' could have null values which are illegal in type '%s'",
10858 buf_ptr(&actual_elem_type->name),
10859 buf_ptr(&wanted_elem_type->name)));
10856 buf_ptr(&actual_type->name),
10857 buf_ptr(&wanted_type->name)));
1086010858 } else {
1086110859 add_error_note(ira->codegen, parent_msg, source_node,
1086210860 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'",
10863 buf_ptr(&cast_result->data.bad_allows_zero->wanted_type->name),
10864 buf_ptr(&cast_result->data.bad_allows_zero->actual_type->name)));
10861 buf_ptr(&wanted_type->name),
10862 buf_ptr(&actual_type->name)));
1086510863 }
1086610864 break;
1086710865 }
test/compile_errors.zig+37
......@@ -1,6 +1,42 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.addTest(
5 "implicit cast between C pointer and Zig pointer - bad const/align/child",
6 \\export fn a() void {
7 \\ var x: [*c]u8 = undefined;
8 \\ var y: *align(4) u8 = x;
9 \\}
10 \\export fn b() void {
11 \\ var x: [*c]const u8 = undefined;
12 \\ var y: *u8 = x;
13 \\}
14 \\export fn c() void {
15 \\ var x: [*c]u8 = undefined;
16 \\ var y: *u32 = x;
17 \\}
18 \\export fn d() void {
19 \\ var y: *align(1) u32 = undefined;
20 \\ var x: [*c]u32 = y;
21 \\}
22 \\export fn e() void {
23 \\ var y: *const u8 = undefined;
24 \\ var x: [*c]u8 = y;
25 \\}
26 \\export fn f() void {
27 \\ var y: *u8 = undefined;
28 \\ var x: [*c]u32 = y;
29 \\}
30 ,
31 ".tmp_source.zig:3:27: error: cast increases pointer alignment",
32 ".tmp_source.zig:7:18: error: cast discards const qualifier",
33 ".tmp_source.zig:11:19: error: expected type '*u32', found '[*c]u8'",
34 ".tmp_source.zig:11:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'",
35 ".tmp_source.zig:15:22: error: cast increases pointer alignment",
36 ".tmp_source.zig:19:21: error: cast discards const qualifier",
37 ".tmp_source.zig:23:22: error: expected type '[*c]u32', found '*u8'",
38 );
39
440 cases.addTest(
541 "implicit casting null c pointer to zig pointer",
642 \\comptime {
......@@ -39,6 +75,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3975 \\}
4076 ,
4177 ".tmp_source.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",
78 ".tmp_source.zig:6:24: note: pointer type child '[*c]const u8' cannot cast into pointer type child '[*]const u8'",
4279 ".tmp_source.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'",
4380 ".tmp_source.zig:13:35: error: expected type '[*c]const [*c]u8', found '*[*]u8'",
4481 ".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]u8'",