| author | |
| committer | |
| log | ed7328119f2194f1b64085c08c88a5a656bfc597 |
| tree | 8e31d116453d96d925d5dec4f272bad61fbe3078 |
| parent | 8f3e1ea0f07cdc7e94b0816ae3c58733df0f2786 |
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 | 9711 | @tagName(dest_ty.zigTypeTag()), dest_ty, |
| 9712 | 9712 | }); |
| 9713 | 9713 | } |
| 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); | |
| 9718 | 9715 | } |
| 9719 | 9716 | |
| 9720 | 9717 | fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -12096,6 +12093,14 @@ fn coerce( |
| 12096 | 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 | 12105 | .Int => { |
| 12101 | 12106 | // integer widening |
| ... | ... | @@ -12808,7 +12813,7 @@ fn coerceCompatiblePtrs( |
| 12808 | 12813 | inst: Air.Inst.Ref, |
| 12809 | 12814 | inst_src: LazySrcLoc, |
| 12810 | 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 | 12817 | // The comptime Value representation is compatible with both types. |
| 12813 | 12818 | return sema.addConstant(dest_ty, val); |
| 12814 | 12819 | } |
test/behavior/cast.zig+14| ... | ... | @@ -106,3 +106,17 @@ test "comptime_int @intToFloat" { |
| 106 | 106 | try expect(result == 0x1_0000_0000_0000_0000.0); |
| 107 | 107 | } |
| 108 | 108 | } |
| 109 | ||
| 110 | test "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 | ||
| 117 | fn 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 | 417 | @ptrCast(*u8, value.?).* += 1; |
| 418 | 418 | } |
| 419 | 419 | |
| 420 | test "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 | ||
| 427 | fn 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 | ||
| 434 | 420 | test "*usize to *void" { |
| 435 | 421 | var i = @as(usize, 0); |
| 436 | 422 | var v = @ptrCast(*void, &i); |