authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-03-02 21:52:49-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-03 13:08:14-07:00
logb6a6f05c0d139ebb572bbc6672d8ecfe5e63d89f
tree323110982fdd6b4a1a76a9388eb2bf14b4d5560a
parentb6f1a8612bc5120b729f94031119315334e54e35

stage2: support @ptrCast for slices with an offset


3 files changed, 27 insertions(+), 15 deletions(-)

src/Sema.zig+17-10
...@@ -15363,7 +15363,7 @@ fn unionFieldVal(...@@ -15363,7 +15363,7 @@ fn unionFieldVal(
15363 return sema.addConstant(field.ty, tag_and_val.val);15363 return sema.addConstant(field.ty, tag_and_val.val);
15364 } else {15364 } else {
15365 const old_ty = union_ty.unionFieldType(tag_and_val.tag);15365 const old_ty = union_ty.unionFieldType(tag_and_val.tag);
15366 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty);15366 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);
15367 return sema.addConstant(field.ty, new_val);15367 return sema.addConstant(field.ty, new_val);
15368 }15368 }
15369 },15369 },
...@@ -16470,7 +16470,7 @@ fn storePtrVal(...@@ -16470,7 +16470,7 @@ fn storePtrVal(
16470 var kit = try beginComptimePtrMutation(sema, block, src, ptr_val);16470 var kit = try beginComptimePtrMutation(sema, block, src, ptr_val);
16471 try sema.checkComptimeVarStore(block, src, kit.decl_ref_mut);16471 try sema.checkComptimeVarStore(block, src, kit.decl_ref_mut);
1647216472
16473 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, kit.ty);16473 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, kit.ty, 0);
1647416474
16475 const arena = kit.beginArena(sema.gpa);16475 const arena = kit.beginArena(sema.gpa);
16476 defer kit.finishArena();16476 defer kit.finishArena();
...@@ -16764,6 +16764,8 @@ fn beginComptimePtrMutation(...@@ -16764,6 +16764,8 @@ fn beginComptimePtrMutation(
16764const ComptimePtrLoadKit = struct {16764const ComptimePtrLoadKit = struct {
16765 /// The Value of the Decl that owns this memory.16765 /// The Value of the Decl that owns this memory.
16766 root_val: Value,16766 root_val: Value,
16767 /// The Type of the Decl that owns this memory.
16768 root_ty: Type,
16767 /// Parent Value.16769 /// Parent Value.
16768 val: Value,16770 val: Value,
16769 /// The Type of the parent Value.16771 /// The Type of the parent Value.
...@@ -16794,6 +16796,7 @@ fn beginComptimePtrLoad(...@@ -16794,6 +16796,7 @@ fn beginComptimePtrLoad(
16794 if (decl_val.tag() == .variable) return error.RuntimeLoad;16796 if (decl_val.tag() == .variable) return error.RuntimeLoad;
16795 return ComptimePtrLoadKit{16797 return ComptimePtrLoadKit{
16796 .root_val = decl_val,16798 .root_val = decl_val,
16799 .root_ty = decl.ty,
16797 .val = decl_val,16800 .val = decl_val,
16798 .ty = decl.ty,16801 .ty = decl.ty,
16799 .byte_offset = 0,16802 .byte_offset = 0,
...@@ -16806,6 +16809,7 @@ fn beginComptimePtrLoad(...@@ -16806,6 +16809,7 @@ fn beginComptimePtrLoad(
16806 if (decl_val.tag() == .variable) return error.RuntimeLoad;16809 if (decl_val.tag() == .variable) return error.RuntimeLoad;
16807 return ComptimePtrLoadKit{16810 return ComptimePtrLoadKit{
16808 .root_val = decl_val,16811 .root_val = decl_val,
16812 .root_ty = decl.ty,
16809 .val = decl_val,16813 .val = decl_val,
16810 .ty = decl.ty,16814 .ty = decl.ty,
16811 .byte_offset = 0,16815 .byte_offset = 0,
...@@ -16840,6 +16844,7 @@ fn beginComptimePtrLoad(...@@ -16840,6 +16844,7 @@ fn beginComptimePtrLoad(
16840 };16844 };
16841 return ComptimePtrLoadKit{16845 return ComptimePtrLoadKit{
16842 .root_val = parent.root_val,16846 .root_val = parent.root_val,
16847 .root_ty = parent.ty,
16843 .val = try parent.val.elemValue(sema.arena, elem_ptr.index),16848 .val = try parent.val.elemValue(sema.arena, elem_ptr.index),
16844 .ty = elem_ty,16849 .ty = elem_ty,
16845 .byte_offset = byte_offset,16850 .byte_offset = byte_offset,
...@@ -16855,6 +16860,7 @@ fn beginComptimePtrLoad(...@@ -16855,6 +16860,7 @@ fn beginComptimePtrLoad(
16855 }16860 }
16856 return ComptimePtrLoadKit{16861 return ComptimePtrLoadKit{
16857 .root_val = parent.root_val,16862 .root_val = parent.root_val,
16863 .root_ty = parent.ty,
16858 .val = parent.val,16864 .val = parent.val,
16859 .ty = parent.ty,16865 .ty = parent.ty,
16860 .byte_offset = parent.byte_offset,16866 .byte_offset = parent.byte_offset,
...@@ -16882,6 +16888,7 @@ fn beginComptimePtrLoad(...@@ -16882,6 +16888,7 @@ fn beginComptimePtrLoad(
16882 };16888 };
16883 return ComptimePtrLoadKit{16889 return ComptimePtrLoadKit{
16884 .root_val = parent.root_val,16890 .root_val = parent.root_val,
16891 .root_ty = parent.ty,
16885 .val = try parent.val.fieldValue(sema.arena, field_index),16892 .val = try parent.val.fieldValue(sema.arena, field_index),
16886 .ty = parent.ty.structFieldType(field_index),16893 .ty = parent.ty.structFieldType(field_index),
16887 .byte_offset = byte_offset,16894 .byte_offset = byte_offset,
...@@ -16893,6 +16900,7 @@ fn beginComptimePtrLoad(...@@ -16893,6 +16900,7 @@ fn beginComptimePtrLoad(
16893 const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr);16900 const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr);
16894 return ComptimePtrLoadKit{16901 return ComptimePtrLoadKit{
16895 .root_val = parent.root_val,16902 .root_val = parent.root_val,
16903 .root_ty = parent.root_ty,
16896 .val = parent.val.castTag(.eu_payload).?.data,16904 .val = parent.val.castTag(.eu_payload).?.data,
16897 .ty = parent.ty.errorUnionPayload(),16905 .ty = parent.ty.errorUnionPayload(),
16898 .byte_offset = null,16906 .byte_offset = null,
...@@ -16904,6 +16912,7 @@ fn beginComptimePtrLoad(...@@ -16904,6 +16912,7 @@ fn beginComptimePtrLoad(
16904 const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr);16912 const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr);
16905 return ComptimePtrLoadKit{16913 return ComptimePtrLoadKit{
16906 .root_val = parent.root_val,16914 .root_val = parent.root_val,
16915 .root_ty = parent.root_ty,
16907 .val = parent.val.castTag(.opt_payload).?.data,16916 .val = parent.val.castTag(.opt_payload).?.data,
16908 .ty = try parent.ty.optionalChildAlloc(sema.arena),16917 .ty = try parent.ty.optionalChildAlloc(sema.arena),
16909 .byte_offset = null,16918 .byte_offset = null,
...@@ -16941,7 +16950,7 @@ fn bitCast(...@@ -16941,7 +16950,7 @@ fn bitCast(
1694116950
16942 // TODO validate the type size and other compile errors16951 // TODO validate the type size and other compile errors
16943 if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| {16952 if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| {
16944 const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty);16953 const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty, 0);
16945 return sema.addConstant(dest_ty, result_val);16954 return sema.addConstant(dest_ty, result_val);
16946 }16955 }
16947 try sema.requireRuntimeBlock(block, inst_src);16956 try sema.requireRuntimeBlock(block, inst_src);
...@@ -16955,6 +16964,7 @@ pub fn bitCastVal(...@@ -16955,6 +16964,7 @@ pub fn bitCastVal(
16955 val: Value,16964 val: Value,
16956 old_ty: Type,16965 old_ty: Type,
16957 new_ty: Type,16966 new_ty: Type,
16967 buffer_offset: usize,
16958) !Value {16968) !Value {
16959 if (old_ty.eql(new_ty)) return val;16969 if (old_ty.eql(new_ty)) return val;
1696016970
...@@ -16965,7 +16975,7 @@ pub fn bitCastVal(...@@ -16965,7 +16975,7 @@ pub fn bitCastVal(
16965 const buffer = try sema.gpa.alloc(u8, abi_size);16975 const buffer = try sema.gpa.alloc(u8, abi_size);
16966 defer sema.gpa.free(buffer);16976 defer sema.gpa.free(buffer);
16967 val.writeToMemory(old_ty, target, buffer);16977 val.writeToMemory(old_ty, target, buffer);
16968 return Value.readFromMemory(new_ty, target, buffer, sema.arena);16978 return Value.readFromMemory(new_ty, target, buffer[buffer_offset..], sema.arena);
16969}16979}
1697016980
16971fn coerceArrayPtrToSlice(16981fn coerceArrayPtrToSlice(
...@@ -19831,13 +19841,10 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -19831,13 +19841,10 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
19831 // The Type it is stored as in the compiler has an ABI size greater or equal to19841 // The Type it is stored as in the compiler has an ABI size greater or equal to
19832 // the ABI size of `load_ty`. We may perform the bitcast based on19842 // the ABI size of `load_ty`. We may perform the bitcast based on
19833 // `parent.val` alone (more efficient).19843 // `parent.val` alone (more efficient).
19834 return try sema.bitCastVal(block, src, parent.val, parent.ty, load_ty);19844 return try sema.bitCastVal(block, src, parent.val, parent.ty, load_ty, 0);
19845 } else {
19846 return try sema.bitCastVal(block, src, parent.root_val, parent.root_ty, load_ty, parent.byte_offset.?);
19835 }19847 }
19836
19837 // The Type it is stored as in the compiler has an ABI size less than the ABI size
19838 // of `load_ty`. The bitcast must be performed based on the `parent.root_val`
19839 // and reinterpreted starting at `parent.byte_offset`.
19840 return sema.fail(block, src, "TODO: implement bitcast with index offset", .{});
19841}19848}
1984219849
19843/// Used to convert a u64 value to a usize value, emitting a compile error if the number19850/// Used to convert a u64 value to a usize value, emitting a compile error if the number
src/type.zig+4-2
...@@ -5287,8 +5287,10 @@ pub const Type = extern union {...@@ -5287,8 +5287,10 @@ pub const Type = extern union {
5287 // type, we change it to 0 here. If this causes an assertion trip because the5287 // type, we change it to 0 here. If this causes an assertion trip because the
5288 // pointee type needs to be resolved more, that needs to be done before calling5288 // pointee type needs to be resolved more, that needs to be done before calling
5289 // this ptr() function.5289 // this ptr() function.
5290 if (d.@"align" != 0 and d.@"align" == d.pointee_type.abiAlignment(target)) {5290 if (d.@"align" != 0) {
5291 d.@"align" = 0;5291 if (d.pointee_type.zigTypeTag() == .Opaque or d.@"align" == d.pointee_type.abiAlignment(target)) {
5292 d.@"align" = 0;
5293 }
5292 }5294 }
52935295
5294 // Canonicalize host_size. If it matches the bit size of the pointee type,5296 // Canonicalize host_size. If it matches the bit size of the pointee type,
test/behavior/ptrcast.zig+6-3
...@@ -4,7 +4,9 @@ const expect = std.testing.expect;...@@ -4,7 +4,9 @@ const expect = std.testing.expect;
4const native_endian = builtin.target.cpu.arch.endian();4const native_endian = builtin.target.cpu.arch.endian();
55
6test "reinterpret bytes as integer with nonzero offset" {6test "reinterpret bytes as integer with nonzero offset" {
7 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
810
9 try testReinterpretBytesAsInteger();11 try testReinterpretBytesAsInteger();
10 comptime try testReinterpretBytesAsInteger();12 comptime try testReinterpretBytesAsInteger();
...@@ -43,7 +45,6 @@ fn testReinterpretBytesAsExternStruct() !void {...@@ -43,7 +45,6 @@ fn testReinterpretBytesAsExternStruct() !void {
43test "reinterpret struct field at comptime" {45test "reinterpret struct field at comptime" {
44 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO46 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
45 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO47 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
46 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
47 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
48 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO49 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4950
...@@ -75,7 +76,9 @@ test "comptime ptrcast keeps larger alignment" {...@@ -75,7 +76,9 @@ test "comptime ptrcast keeps larger alignment" {
75}76}
7677
77test "implicit optional pointer to optional anyopaque pointer" {78test "implicit optional pointer to optional anyopaque pointer" {
78 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO79 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
81 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7982
80 var buf: [4]u8 = "aoeu".*;83 var buf: [4]u8 = "aoeu".*;
81 var x: ?[*]u8 = &buf;84 var x: ?[*]u8 = &buf;