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...@@ -8683,16 +8683,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
8683 bool actual_opt_or_ptr = actual_ptr_type != nullptr &&8683 bool actual_opt_or_ptr = actual_ptr_type != nullptr &&
8684 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);8684 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);
8685 if (wanted_opt_or_ptr && actual_opt_or_ptr) {8685 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 }
8696 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,8686 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
8697 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);8687 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
8698 if (child.id == ConstCastResultIdInvalid)8688 if (child.id == ConstCastResultIdInvalid)
...@@ -8705,6 +8695,16 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted...@@ -8705,6 +8695,16 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
8705 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;8695 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
8706 return result;8696 return result;
8707 }8697 }
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 }
8708 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {8708 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
8709 result.id = ConstCastResultIdInvalid;8709 result.id = ConstCastResultIdInvalid;
8710 return result;8710 return result;
...@@ -10846,22 +10846,20 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa...@@ -10846,22 +10846,20 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
10846 break;10846 break;
10847 }10847 }
10848 case ConstCastResultIdBadAllowsZero: {10848 case ConstCastResultIdBadAllowsZero: {
10849 bool wanted_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->wanted_type);10849 ZigType *wanted_type = 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);10850 ZigType *actual_type = 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);10851 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type);
10852 ZigType *actual_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->actual_type);10852 bool actual_allows_zero = ptr_allows_addr_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;
10855 if (actual_allows_zero && !wanted_allows_zero) {10853 if (actual_allows_zero && !wanted_allows_zero) {
10856 add_error_note(ira->codegen, parent_msg, source_node,10854 add_error_note(ira->codegen, parent_msg, source_node,
10857 buf_sprintf("'%s' could have null values which are illegal in type '%s'",10855 buf_sprintf("'%s' could have null values which are illegal in type '%s'",
10858 buf_ptr(&actual_elem_type->name),10856 buf_ptr(&actual_type->name),
10859 buf_ptr(&wanted_elem_type->name)));10857 buf_ptr(&wanted_type->name)));
10860 } else {10858 } else {
10861 add_error_note(ira->codegen, parent_msg, source_node,10859 add_error_note(ira->codegen, parent_msg, source_node,
10862 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'",10860 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'",
10863 buf_ptr(&cast_result->data.bad_allows_zero->wanted_type->name),10861 buf_ptr(&wanted_type->name),
10864 buf_ptr(&cast_result->data.bad_allows_zero->actual_type->name)));10862 buf_ptr(&actual_type->name)));
10865 }10863 }
10866 break;10864 break;
10867 }10865 }
test/compile_errors.zig+37
...@@ -1,6 +1,42 @@...@@ -1,6 +1,42 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub 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
4 cases.addTest(40 cases.addTest(
5 "implicit casting null c pointer to zig pointer",41 "implicit casting null c pointer to zig pointer",
6 \\comptime {42 \\comptime {
...@@ -39,6 +75,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -39,6 +75,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
39 \\}75 \\}
40 ,76 ,
41 ".tmp_source.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",77 ".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'",
42 ".tmp_source.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'",79 ".tmp_source.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'",
43 ".tmp_source.zig:13:35: error: expected type '[*c]const [*c]u8', found '*[*]u8'",80 ".tmp_source.zig:13:35: error: expected type '[*c]const [*c]u8', found '*[*]u8'",
44 ".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]u8'",81 ".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]u8'",