mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 19:23:08 +00:00
parent
59de24817e
commit
e03c770145
38
src/ir.cpp
38
src/ir.cpp
@ -8683,16 +8683,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
|||||||
bool actual_opt_or_ptr = actual_ptr_type != nullptr &&
|
bool actual_opt_or_ptr = actual_ptr_type != nullptr &&
|
||||||
(actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);
|
(actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);
|
||||||
if (wanted_opt_or_ptr && actual_opt_or_ptr) {
|
if (wanted_opt_or_ptr && actual_opt_or_ptr) {
|
||||||
bool ok_allows_zero = (wanted_allows_zero &&
|
|
||||||
(actual_allows_zero || wanted_ptr_type->data.pointer.is_const)) ||
|
|
||||||
(!wanted_allows_zero && !actual_allows_zero);
|
|
||||||
if (!ok_allows_zero) {
|
|
||||||
result.id = ConstCastResultIdBadAllowsZero;
|
|
||||||
result.data.bad_allows_zero = allocate_nonzero<ConstCastBadAllowsZero>(1);
|
|
||||||
result.data.bad_allows_zero->wanted_type = wanted_type;
|
|
||||||
result.data.bad_allows_zero->actual_type = actual_type;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
|
ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
|
||||||
actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
|
actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
|
||||||
if (child.id == ConstCastResultIdInvalid)
|
if (child.id == ConstCastResultIdInvalid)
|
||||||
@ -8705,6 +8695,16 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
|||||||
result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
|
result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
bool ok_allows_zero = (wanted_allows_zero &&
|
||||||
|
(actual_allows_zero || wanted_ptr_type->data.pointer.is_const)) ||
|
||||||
|
(!wanted_allows_zero && !actual_allows_zero);
|
||||||
|
if (!ok_allows_zero) {
|
||||||
|
result.id = ConstCastResultIdBadAllowsZero;
|
||||||
|
result.data.bad_allows_zero = allocate_nonzero<ConstCastBadAllowsZero>(1);
|
||||||
|
result.data.bad_allows_zero->wanted_type = wanted_type;
|
||||||
|
result.data.bad_allows_zero->actual_type = actual_type;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
|
if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
|
||||||
result.id = ConstCastResultIdInvalid;
|
result.id = ConstCastResultIdInvalid;
|
||||||
return result;
|
return result;
|
||||||
@ -10846,22 +10846,20 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConstCastResultIdBadAllowsZero: {
|
case ConstCastResultIdBadAllowsZero: {
|
||||||
bool wanted_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->wanted_type);
|
ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type;
|
||||||
bool actual_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->actual_type);
|
ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type;
|
||||||
ZigType *wanted_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->wanted_type);
|
bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type);
|
||||||
ZigType *actual_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->actual_type);
|
bool actual_allows_zero = ptr_allows_addr_zero(actual_type);
|
||||||
ZigType *wanted_elem_type = wanted_ptr_type->data.pointer.child_type;
|
|
||||||
ZigType *actual_elem_type = actual_ptr_type->data.pointer.child_type;
|
|
||||||
if (actual_allows_zero && !wanted_allows_zero) {
|
if (actual_allows_zero && !wanted_allows_zero) {
|
||||||
add_error_note(ira->codegen, parent_msg, source_node,
|
add_error_note(ira->codegen, parent_msg, source_node,
|
||||||
buf_sprintf("'%s' could have null values which are illegal in type '%s'",
|
buf_sprintf("'%s' could have null values which are illegal in type '%s'",
|
||||||
buf_ptr(&actual_elem_type->name),
|
buf_ptr(&actual_type->name),
|
||||||
buf_ptr(&wanted_elem_type->name)));
|
buf_ptr(&wanted_type->name)));
|
||||||
} else {
|
} else {
|
||||||
add_error_note(ira->codegen, parent_msg, source_node,
|
add_error_note(ira->codegen, parent_msg, source_node,
|
||||||
buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'",
|
buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'",
|
||||||
buf_ptr(&cast_result->data.bad_allows_zero->wanted_type->name),
|
buf_ptr(&wanted_type->name),
|
||||||
buf_ptr(&cast_result->data.bad_allows_zero->actual_type->name)));
|
buf_ptr(&actual_type->name)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,42 @@
|
|||||||
const tests = @import("tests.zig");
|
const tests = @import("tests.zig");
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
|
cases.addTest(
|
||||||
|
"implicit cast between C pointer and Zig pointer - bad const/align/child",
|
||||||
|
\\export fn a() void {
|
||||||
|
\\ var x: [*c]u8 = undefined;
|
||||||
|
\\ var y: *align(4) u8 = x;
|
||||||
|
\\}
|
||||||
|
\\export fn b() void {
|
||||||
|
\\ var x: [*c]const u8 = undefined;
|
||||||
|
\\ var y: *u8 = x;
|
||||||
|
\\}
|
||||||
|
\\export fn c() void {
|
||||||
|
\\ var x: [*c]u8 = undefined;
|
||||||
|
\\ var y: *u32 = x;
|
||||||
|
\\}
|
||||||
|
\\export fn d() void {
|
||||||
|
\\ var y: *align(1) u32 = undefined;
|
||||||
|
\\ var x: [*c]u32 = y;
|
||||||
|
\\}
|
||||||
|
\\export fn e() void {
|
||||||
|
\\ var y: *const u8 = undefined;
|
||||||
|
\\ var x: [*c]u8 = y;
|
||||||
|
\\}
|
||||||
|
\\export fn f() void {
|
||||||
|
\\ var y: *u8 = undefined;
|
||||||
|
\\ var x: [*c]u32 = y;
|
||||||
|
\\}
|
||||||
|
,
|
||||||
|
".tmp_source.zig:3:27: error: cast increases pointer alignment",
|
||||||
|
".tmp_source.zig:7:18: error: cast discards const qualifier",
|
||||||
|
".tmp_source.zig:11:19: error: expected type '*u32', found '[*c]u8'",
|
||||||
|
".tmp_source.zig:11:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'",
|
||||||
|
".tmp_source.zig:15:22: error: cast increases pointer alignment",
|
||||||
|
".tmp_source.zig:19:21: error: cast discards const qualifier",
|
||||||
|
".tmp_source.zig:23:22: error: expected type '[*c]u32', found '*u8'",
|
||||||
|
);
|
||||||
|
|
||||||
cases.addTest(
|
cases.addTest(
|
||||||
"implicit casting null c pointer to zig pointer",
|
"implicit casting null c pointer to zig pointer",
|
||||||
\\comptime {
|
\\comptime {
|
||||||
@ -39,6 +75,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||||||
\\}
|
\\}
|
||||||
,
|
,
|
||||||
".tmp_source.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",
|
".tmp_source.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",
|
||||||
|
".tmp_source.zig:6:24: note: pointer type child '[*c]const u8' cannot cast into pointer type child '[*]const u8'",
|
||||||
".tmp_source.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'",
|
".tmp_source.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'",
|
||||||
".tmp_source.zig:13:35: error: expected type '[*c]const [*c]u8', found '*[*]u8'",
|
".tmp_source.zig:13:35: error: expected type '[*c]const [*c]u8', found '*[*]u8'",
|
||||||
".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]u8'",
|
".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]u8'",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user