parent
285e2f62ba
commit
6f05e8d1be
34
src/ir.cpp
34
src/ir.cpp
|
@ -8669,33 +8669,41 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
|||
}
|
||||
|
||||
// pointer const
|
||||
if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer) {
|
||||
ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
|
||||
actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const);
|
||||
ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type);
|
||||
ZigType *actual_ptr_type = get_src_ptr_type(actual_type);
|
||||
bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC;
|
||||
bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC;
|
||||
if ((wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer) ||
|
||||
(wanted_ptr_type != nullptr && actual_is_c_ptr) ||
|
||||
(actual_ptr_type != nullptr && wanted_is_c_ptr))
|
||||
{
|
||||
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);
|
||||
if (child.id == ConstCastResultIdInvalid)
|
||||
return child;
|
||||
if (child.id != ConstCastResultIdOk) {
|
||||
result.id = ConstCastResultIdPointerChild;
|
||||
result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1);
|
||||
result.data.pointer_mismatch->child = child;
|
||||
result.data.pointer_mismatch->wanted_child = wanted_type->data.pointer.child_type;
|
||||
result.data.pointer_mismatch->actual_child = actual_type->data.pointer.child_type;
|
||||
result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type;
|
||||
result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
|
||||
return result;
|
||||
}
|
||||
if ((err = type_resolve(g, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
|
||||
if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
|
||||
result.id = ConstCastResultIdInvalid;
|
||||
return result;
|
||||
}
|
||||
if ((err = type_resolve(g, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
|
||||
if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
|
||||
result.id = ConstCastResultIdInvalid;
|
||||
return result;
|
||||
}
|
||||
if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
|
||||
(!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
|
||||
(!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
|
||||
actual_type->data.pointer.bit_offset_in_host == wanted_type->data.pointer.bit_offset_in_host &&
|
||||
actual_type->data.pointer.host_int_bytes == wanted_type->data.pointer.host_int_bytes &&
|
||||
get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type))
|
||||
bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len;
|
||||
if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr) &&
|
||||
(!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
|
||||
(!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
|
||||
actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host &&
|
||||
actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes &&
|
||||
get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -97,3 +97,13 @@ test "peer type resolution with C pointers" {
|
|||
expect(@typeOf(x3) == [*c]u8);
|
||||
expect(@typeOf(x4) == [*c]u8);
|
||||
}
|
||||
|
||||
test "implicit casting between C pointer and optional non-C pointer" {
|
||||
var slice: []const u8 = "aoeu";
|
||||
const opt_many_ptr: ?[*]const u8 = slice.ptr;
|
||||
var ptr_opt_many_ptr = &opt_many_ptr;
|
||||
var c_ptr: [*c]const [*c]const u8 = ptr_opt_many_ptr;
|
||||
expect(c_ptr.*.* == 'a');
|
||||
ptr_opt_many_ptr = c_ptr;
|
||||
expect(ptr_opt_many_ptr.*.?[1] == 'o');
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue