diff --git a/src/Sema.zig b/src/Sema.zig index 0629e91bcc..a87e0739e8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9711,10 +9711,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air @tagName(dest_ty.zigTypeTag()), dest_ty, }); } - if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { - return sema.addConstant(dest_ty, val); - } - return block.addBitCast(dest_ty, operand); + return sema.coerceCompatiblePtrs(block, dest_ty, operand, operand_src); } fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -12096,6 +12093,14 @@ fn coerce( else => {}, } } + + // cast from *T and [*]T to *c_void + // but don't do it if the source type is a double pointer + if (dest_info.pointee_type.tag() == .c_void and inst_ty.zigTypeTag() == .Pointer and + inst_ty.childType().zigTypeTag() != .Pointer) + { + return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); + } }, .Int => { // integer widening @@ -12808,7 +12813,7 @@ fn coerceCompatiblePtrs( inst: Air.Inst.Ref, inst_src: LazySrcLoc, ) !Air.Inst.Ref { - if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| { + if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { // The comptime Value representation is compatible with both types. return sema.addConstant(dest_ty, val); } diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 1a5b3c99d2..42e6016061 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -106,3 +106,17 @@ test "comptime_int @intToFloat" { try expect(result == 0x1_0000_0000_0000_0000.0); } } + +test "implicit cast from [*]T to ?*c_void" { + var a = [_]u8{ 3, 2, 1 }; + var runtime_zero: usize = 0; + incrementVoidPtrArray(a[runtime_zero..].ptr, 3); + try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 })); +} + +fn incrementVoidPtrArray(array: ?*c_void, len: usize) void { + var n: usize = 0; + while (n < len) : (n += 1) { + @ptrCast([*]u8, array.?)[n] += 1; + } +} diff --git a/test/behavior/cast_stage1.zig b/test/behavior/cast_stage1.zig index c6d3b5c430..8eb6302e60 100644 --- a/test/behavior/cast_stage1.zig +++ b/test/behavior/cast_stage1.zig @@ -417,20 +417,6 @@ fn incrementVoidPtrValue(value: ?*c_void) void { @ptrCast(*u8, value.?).* += 1; } -test "implicit cast from [*]T to ?*c_void" { - var a = [_]u8{ 3, 2, 1 }; - var runtime_zero: usize = 0; - incrementVoidPtrArray(a[runtime_zero..].ptr, 3); - try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 })); -} - -fn incrementVoidPtrArray(array: ?*c_void, len: usize) void { - var n: usize = 0; - while (n < len) : (n += 1) { - @ptrCast([*]u8, array.?)[n] += 1; - } -} - test "*usize to *void" { var i = @as(usize, 0); var v = @ptrCast(*void, &i);