authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-26 17:55:20-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-26 17:55:20-04:00
logdf7aa9a4f0360945db999f6a6190290eb91d6351
treeeef23c1ab9733469783fdcb2f1d45c37bf705d5f
parent269a53b6afb052ec09f7b26db68219cfeaa0460e
signaturelock-open Commit is signed but in an unrecognized format.

allow implicit optional pointer to optional c_void pointer


2 files changed, 23 insertions(+), 10 deletions(-)

src/ir.cpp+15-10
...@@ -11521,6 +11521,19 @@ static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *sou...@@ -11521,6 +11521,19 @@ static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *sou
11521 return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type);11521 return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type);
11522}11522}
1152311523
11524static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {
11525 if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer;
11526 if (ty->id == ZigTypeIdFn) return true;
11527 if (ty->id == ZigTypeIdPromise) return true;
11528 if (ty->id == ZigTypeIdOptional) {
11529 ZigType *ptr_ty = ty->data.maybe.child_type;
11530 if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer;
11531 if (ptr_ty->id == ZigTypeIdFn) return true;
11532 if (ptr_ty->id == ZigTypeIdPromise) return true;
11533 }
11534 return false;
11535}
11536
11524static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,11537static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
11525 ZigType *wanted_type, IrInstruction *value)11538 ZigType *wanted_type, IrInstruction *value)
11526{11539{
...@@ -11895,27 +11908,19 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11895,27 +11908,19 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1189511908
11896 // cast from *T and [*]T to *c_void and ?*c_void11909 // cast from *T and [*]T to *c_void and ?*c_void
11897 // but don't do it if the actual type is a double pointer11910 // but don't do it if the actual type is a double pointer
11898 if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.child_type->id != ZigTypeIdPointer) {11911 if (is_pointery_and_elem_is_not_pointery(actual_type)) {
11899 ZigType *dest_ptr_type = nullptr;11912 ZigType *dest_ptr_type = nullptr;
11900 if (wanted_type->id == ZigTypeIdPointer &&11913 if (wanted_type->id == ZigTypeIdPointer &&
11901 wanted_type->data.pointer.ptr_len == PtrLenSingle &&
11902 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void)11914 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void)
11903 {11915 {
11904 dest_ptr_type = wanted_type;11916 dest_ptr_type = wanted_type;
11905 } else if (wanted_type->id == ZigTypeIdOptional &&11917 } else if (wanted_type->id == ZigTypeIdOptional &&
11906 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer &&11918 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer &&
11907 wanted_type->data.maybe.child_type->data.pointer.ptr_len == PtrLenSingle &&
11908 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void)11919 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void)
11909 {11920 {
11910 dest_ptr_type = wanted_type->data.maybe.child_type;11921 dest_ptr_type = wanted_type->data.maybe.child_type;
11911 }11922 }
11912 if (dest_ptr_type != nullptr &&11923 if (dest_ptr_type != nullptr) {
11913 (!actual_type->data.pointer.is_const || dest_ptr_type->data.pointer.is_const) &&
11914 (!actual_type->data.pointer.is_volatile || dest_ptr_type->data.pointer.is_volatile) &&
11915 actual_type->data.pointer.bit_offset_in_host == dest_ptr_type->data.pointer.bit_offset_in_host &&
11916 actual_type->data.pointer.host_int_bytes == dest_ptr_type->data.pointer.host_int_bytes &&
11917 get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, dest_ptr_type))
11918 {
11919 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true);11924 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true);
11920 }11925 }
11921 }11926 }
test/stage1/behavior/ptrcast.zig+8
...@@ -58,3 +58,11 @@ test "comptime ptrcast keeps larger alignment" {...@@ -58,3 +58,11 @@ test "comptime ptrcast keeps larger alignment" {
58 std.debug.assert(@typeOf(p) == [*]align(@alignOf(u32)) const u8);58 std.debug.assert(@typeOf(p) == [*]align(@alignOf(u32)) const u8);
59 }59 }
60}60}
61
62test "implicit optional pointer to optional c_void pointer" {
63 var buf: [4]u8 = "aoeu";
64 var x: ?[*]u8 = &buf;
65 var y: ?*c_void = x;
66 var z = @ptrCast(*[4]u8, y);
67 expect(std.mem.eql(u8, z, "aoeu"));
68}