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
97119711 @tagName(dest_ty.zigTypeTag()), dest_ty,
97129712 });
97139713 }
9714 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
9715 return sema.addConstant(dest_ty, val);
9716 }
9717 return block.addBitCast(dest_ty, operand);
9714 return sema.coerceCompatiblePtrs(block, dest_ty, operand, operand_src);
97189715}
97199716
97209717fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -12096,6 +12093,14 @@ fn coerce(
1209612093 else => {},
1209712094 }
1209812095 }
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 }
1209912104 },
1210012105 .Int => {
1210112106 // integer widening
......@@ -12808,7 +12813,7 @@ fn coerceCompatiblePtrs(
1280812813 inst: Air.Inst.Ref,
1280912814 inst_src: LazySrcLoc,
1281012815) !Air.Inst.Ref {
12811 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
12816 if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| {
1281212817 // The comptime Value representation is compatible with both types.
1281312818 return sema.addConstant(dest_ty, val);
1281412819 }
test/behavior/cast.zig+14
......@@ -106,3 +106,17 @@ test "comptime_int @intToFloat" {
106106 try expect(result == 0x1_0000_0000_0000_0000.0);
107107 }
108108}
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 {
417417 @ptrCast(*u8, value.?).* += 1;
418418}
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
434420test "*usize to *void" {
435421 var i = @as(usize, 0);
436422 var v = @ptrCast(*void, &i);