authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-25 11:34:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-25 11:34:23-07:00
loged7328119f2194f1b64085c08c88a5a656bfc597
tree8e31d116453d96d925d5dec4f272bad61fbe3078
parent8f3e1ea0f07cdc7e94b0816ae3c58733df0f2786

Sema: implement coercion from pointers to `*c_void`


3 files changed, 24 insertions(+), 19 deletions(-)

src/Sema.zig+10-5
...@@ -9711,10 +9711,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9711,10 +9711,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9711 @tagName(dest_ty.zigTypeTag()), dest_ty,9711 @tagName(dest_ty.zigTypeTag()), dest_ty,
9712 });9712 });
9713 }9713 }
9714 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {9714 return sema.coerceCompatiblePtrs(block, dest_ty, operand, operand_src);
9715 return sema.addConstant(dest_ty, val);
9716 }
9717 return block.addBitCast(dest_ty, operand);
9718}9715}
97199716
9720fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {9717fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -12096,6 +12093,14 @@ fn coerce(...@@ -12096,6 +12093,14 @@ fn coerce(
12096 else => {},12093 else => {},
12097 }12094 }
12098 }12095 }
12096
12097 // cast from *T and [*]T to *c_void
12098 // but don't do it if the source type is a double pointer
12099 if (dest_info.pointee_type.tag() == .c_void and inst_ty.zigTypeTag() == .Pointer and
12100 inst_ty.childType().zigTypeTag() != .Pointer)
12101 {
12102 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
12103 }
12099 },12104 },
12100 .Int => {12105 .Int => {
12101 // integer widening12106 // integer widening
...@@ -12808,7 +12813,7 @@ fn coerceCompatiblePtrs(...@@ -12808,7 +12813,7 @@ fn coerceCompatiblePtrs(
12808 inst: Air.Inst.Ref,12813 inst: Air.Inst.Ref,
12809 inst_src: LazySrcLoc,12814 inst_src: LazySrcLoc,
12810) !Air.Inst.Ref {12815) !Air.Inst.Ref {
12811 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {12816 if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| {
12812 // The comptime Value representation is compatible with both types.12817 // The comptime Value representation is compatible with both types.
12813 return sema.addConstant(dest_ty, val);12818 return sema.addConstant(dest_ty, val);
12814 }12819 }
test/behavior/cast.zig+14
...@@ -106,3 +106,17 @@ test "comptime_int @intToFloat" {...@@ -106,3 +106,17 @@ test "comptime_int @intToFloat" {
106 try expect(result == 0x1_0000_0000_0000_0000.0);106 try expect(result == 0x1_0000_0000_0000_0000.0);
107 }107 }
108}108}
109
110test "implicit cast from [*]T to ?*c_void" {
111 var a = [_]u8{ 3, 2, 1 };
112 var runtime_zero: usize = 0;
113 incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
114 try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
115}
116
117fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
118 var n: usize = 0;
119 while (n < len) : (n += 1) {
120 @ptrCast([*]u8, array.?)[n] += 1;
121 }
122}
test/behavior/cast_stage1.zig-14
...@@ -417,20 +417,6 @@ fn incrementVoidPtrValue(value: ?*c_void) void {...@@ -417,20 +417,6 @@ fn incrementVoidPtrValue(value: ?*c_void) void {
417 @ptrCast(*u8, value.?).* += 1;417 @ptrCast(*u8, value.?).* += 1;
418}418}
419419
420test "implicit cast from [*]T to ?*c_void" {
421 var a = [_]u8{ 3, 2, 1 };
422 var runtime_zero: usize = 0;
423 incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
424 try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
425}
426
427fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
428 var n: usize = 0;
429 while (n < len) : (n += 1) {
430 @ptrCast([*]u8, array.?)[n] += 1;
431 }
432}
433
434test "*usize to *void" {420test "*usize to *void" {
435 var i = @as(usize, 0);421 var i = @as(usize, 0);
436 var v = @ptrCast(*void, &i);422 var v = @ptrCast(*void, &i);