Skip to content

Commit e03c770

Browse files
committed
compile error tests for implicit C pointer casting
See #1059
1 parent 59de248 commit e03c770

File tree

2 files changed

+55
-20
lines changed

2 files changed

+55
-20
lines changed

src/ir.cpp

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,42 @@
11
const tests = @import("tests.zig");
22

33
pub 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'",

0 commit comments

Comments
 (0)