| author | |
| committer | |
| log | a8428b777c588e2dedfaebdd8c22a5b838d6b5ee |
| tree | d45f95557ee4a08febef2766efb628202c5ca3e7 |
| parent | ec3f362ae9722415223d15270ae58cfd3b50ddd0 |
34 files changed, 918 insertions(+), 181 deletions(-)
doc/langref.html.in+7| ... | @@ -5769,6 +5769,13 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val | ... | @@ -5769,6 +5769,13 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 5769 | <p>Returns a {#link|pointer|Pointers#} type with the properties specified by the arguments.</p> | 5769 | <p>Returns a {#link|pointer|Pointers#} type with the properties specified by the arguments.</p> |
| 5770 | {#header_close#} | 5770 | {#header_close#} |
| 5771 | 5771 | ||
| 5772 | {#header_open|@Restricted#} | ||
| 5773 | <pre>{#syntax#}@Restricted( | ||
| 5774 | comptime Pointer: type, | ||
| 5775 | ) type{#endsyntax#}</pre> | ||
| 5776 | <p>Returns a restricted pointer type based on the specified pointer type.</p> | ||
| 5777 | {#header_close#} | ||
| 5778 | |||
| 5772 | {#header_open|@Fn#} | 5779 | {#header_open|@Fn#} |
| 5773 | <pre>{#syntax#}@Fn( | 5780 | <pre>{#syntax#}@Fn( |
| 5774 | comptime param_types: []const type, | 5781 | comptime param_types: []const type, |
lib/std/debug.zig+4| ... | @@ -201,6 +201,10 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { | ... | @@ -201,6 +201,10 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { |
| 201 | @branchHint(.cold); | 201 | @branchHint(.cold); |
| 202 | call("'noreturn' function returned", @returnAddress()); | 202 | call("'noreturn' function returned", @returnAddress()); |
| 203 | } | 203 | } |
| 204 | pub fn corruptRestrictedPointer() noreturn { | ||
| 205 | @branchHint(.cold); | ||
| 206 | call("corrupt restricted pointer value", @returnAddress()); | ||
| 207 | } | ||
| 204 | }; | 208 | }; |
| 205 | } | 209 | } |
| 206 | 210 |
lib/std/debug/no_panic.zig+5| ... | @@ -134,3 +134,8 @@ pub fn noreturnReturned() noreturn { | ... | @@ -134,3 +134,8 @@ pub fn noreturnReturned() noreturn { |
| 134 | @branchHint(.cold); | 134 | @branchHint(.cold); |
| 135 | @trap(); | 135 | @trap(); |
| 136 | } | 136 | } |
| 137 | |||
| 138 | pub fn corruptRestrictedPointer() noreturn { | ||
| 139 | @branchHint(.cold); | ||
| 140 | @trap(); | ||
| 141 | } |
lib/std/debug/simple_panic.zig+4| ... | @@ -126,3 +126,7 @@ pub fn memcpyAlias() noreturn { | ... | @@ -126,3 +126,7 @@ pub fn memcpyAlias() noreturn { |
| 126 | pub fn noreturnReturned() noreturn { | 126 | pub fn noreturnReturned() noreturn { |
| 127 | call("'noreturn' function returned", null); | 127 | call("'noreturn' function returned", null); |
| 128 | } | 128 | } |
| 129 | |||
| 130 | pub fn corruptRestrictedPointer() noreturn { | ||
| 131 | call("corrupt restricted pointer value", null); | ||
| 132 | } |
lib/std/zig/AstGen.zig+10-1| ... | @@ -1208,7 +1208,7 @@ fn nameStratExpr( | ... | @@ -1208,7 +1208,7 @@ fn nameStratExpr( |
| 1208 | const builtin_name = tree.tokenSlice(builtin_token); | 1208 | const builtin_name = tree.tokenSlice(builtin_token); |
| 1209 | const info = BuiltinFn.list.get(builtin_name) orelse return null; | 1209 | const info = BuiltinFn.list.get(builtin_name) orelse return null; |
| 1210 | switch (info.tag) { | 1210 | switch (info.tag) { |
| 1211 | .Enum, .Struct, .Union => { | 1211 | .Restricted, .Enum, .Struct, .Union => { |
| 1212 | var buf: [2]Ast.Node.Index = undefined; | 1212 | var buf: [2]Ast.Node.Index = undefined; |
| 1213 | const params = tree.builtinCallParams(&buf, node).?; | 1213 | const params = tree.builtinCallParams(&buf, node).?; |
| 1214 | return try builtinCall(gz, scope, ri, node, params, false, name_strat); | 1214 | return try builtinCall(gz, scope, ri, node, params, false, name_strat); |
| ... | @@ -9320,6 +9320,15 @@ fn builtinCall( | ... | @@ -9320,6 +9320,15 @@ fn builtinCall( |
| 9320 | }); | 9320 | }); |
| 9321 | return rvalue(gz, ri, result, node); | 9321 | return rvalue(gz, ri, result, node); |
| 9322 | }, | 9322 | }, |
| 9323 | .Restricted => { | ||
| 9324 | const unrestricted_ptr_ty = try typeExpr(gz, scope, params[0]); | ||
| 9325 | const result = try gz.addExtendedPayloadSmall( | ||
| 9326 | .reify_restricted, | ||
| 9327 | @intFromEnum(reify_name_strat), | ||
| 9328 | Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(node), .operand = unrestricted_ptr_ty }, | ||
| 9329 | ); | ||
| 9330 | return rvalue(gz, ri, result, node); | ||
| 9331 | }, | ||
| 9323 | .Fn => { | 9332 | .Fn => { |
| 9324 | const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes); | 9333 | const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes); |
| 9325 | const param_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .fn_param_types); | 9334 | const param_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .fn_param_types); |
lib/std/zig/AstRlAnnotate.zig+1| ... | @@ -903,6 +903,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. | ... | @@ -903,6 +903,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 903 | .error_name, | 903 | .error_name, |
| 904 | .set_runtime_safety, | 904 | .set_runtime_safety, |
| 905 | .Tuple, | 905 | .Tuple, |
| 906 | .Restricted, | ||
| 906 | .wasm_memory_size, | 907 | .wasm_memory_size, |
| 907 | .splat, | 908 | .splat, |
| 908 | .set_float_mode, | 909 | .set_float_mode, |
lib/std/zig/BuiltinFn.zig+8| ... | @@ -110,6 +110,7 @@ pub const Tag = enum { | ... | @@ -110,6 +110,7 @@ pub const Tag = enum { |
| 110 | Int, | 110 | Int, |
| 111 | Tuple, | 111 | Tuple, |
| 112 | Pointer, | 112 | Pointer, |
| 113 | Restricted, | ||
| 113 | Fn, | 114 | Fn, |
| 114 | Struct, | 115 | Struct, |
| 115 | Union, | 116 | Union, |
| ... | @@ -943,6 +944,13 @@ pub const list = list: { | ... | @@ -943,6 +944,13 @@ pub const list = list: { |
| 943 | .param_count = 4, | 944 | .param_count = 4, |
| 944 | }, | 945 | }, |
| 945 | }, | 946 | }, |
| 947 | .{ | ||
| 948 | "@Restricted", | ||
| 949 | .{ | ||
| 950 | .tag = .Restricted, | ||
| 951 | .param_count = 1, | ||
| 952 | }, | ||
| 953 | }, | ||
| 946 | .{ | 954 | .{ |
| 947 | "@Fn", | 955 | "@Fn", |
| 948 | .{ | 956 | .{ |
lib/std/zig/Zir.zig+9-3| ... | @@ -2062,6 +2062,10 @@ pub const Inst = struct { | ... | @@ -2062,6 +2062,10 @@ pub const Inst = struct { |
| 2062 | /// Implements builtin `@Pointer`. | 2062 | /// Implements builtin `@Pointer`. |
| 2063 | /// `operand` is payload index to `ReifyPointer`. | 2063 | /// `operand` is payload index to `ReifyPointer`. |
| 2064 | reify_pointer, | 2064 | reify_pointer, |
| 2065 | /// Implements builtin `@Restricted`. | ||
| 2066 | /// `operand` is payload index to `UnNode`. | ||
| 2067 | /// `small` contains `NameStrategy`. | ||
| 2068 | reify_restricted, | ||
| 2065 | /// Implements builtin `@Fn`. | 2069 | /// Implements builtin `@Fn`. |
| 2066 | /// `operand` is payload index to `ReifyFn`. | 2070 | /// `operand` is payload index to `ReifyFn`. |
| 2067 | reify_fn, | 2071 | reify_fn, |
| ... | @@ -4431,15 +4435,16 @@ fn findTrackableInner( | ... | @@ -4431,15 +4435,16 @@ fn findTrackableInner( |
| 4431 | }, | 4435 | }, |
| 4432 | 4436 | ||
| 4433 | // Reifications need tracking. | 4437 | // Reifications need tracking. |
| 4434 | .reify_enum, | 4438 | .reify_restricted, |
| 4435 | .reify_struct, | 4439 | .reify_struct, |
| 4436 | .reify_union, | 4440 | .reify_union, |
| 4441 | .reify_enum, | ||
| 4437 | => return contents.other.append(gpa, inst), | 4442 | => return contents.other.append(gpa, inst), |
| 4438 | 4443 | ||
| 4439 | // Type declarations need tracking. | 4444 | // Type declarations need tracking. |
| 4440 | .struct_decl, | 4445 | .struct_decl, |
| 4441 | .union_decl, | ||
| 4442 | .enum_decl, | 4446 | .enum_decl, |
| 4447 | .union_decl, | ||
| 4443 | .opaque_decl, | 4448 | .opaque_decl, |
| 4444 | => return contents.type_decls.append(gpa, inst), | 4449 | => return contents.type_decls.append(gpa, inst), |
| 4445 | } | 4450 | } |
| ... | @@ -5232,9 +5237,10 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void { | ... | @@ -5232,9 +5237,10 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void { |
| 5232 | .union_decl, | 5237 | .union_decl, |
| 5233 | .enum_decl, | 5238 | .enum_decl, |
| 5234 | .opaque_decl, | 5239 | .opaque_decl, |
| 5235 | .reify_enum, | 5240 | .reify_restricted, |
| 5236 | .reify_struct, | 5241 | .reify_struct, |
| 5237 | .reify_union, | 5242 | .reify_union, |
| 5243 | .reify_enum, | ||
| 5238 | => {}, // tracked in order, as the owner instructions of explicit container types | 5244 | => {}, // tracked in order, as the owner instructions of explicit container types |
| 5239 | else => unreachable, // assertion failure; not trackable | 5245 | else => unreachable, // assertion failure; not trackable |
| 5240 | }, | 5246 | }, |
src/Air.zig+14| ... | @@ -633,6 +633,16 @@ pub const Inst = struct { | ... | @@ -633,6 +633,16 @@ pub const Inst = struct { |
| 633 | /// wrap from E to E!T | 633 | /// wrap from E to E!T |
| 634 | /// Uses the `ty_op` field. | 634 | /// Uses the `ty_op` field. |
| 635 | wrap_errunion_err, | 635 | wrap_errunion_err, |
| 636 | /// Converts a runtime restricted pointer into the corresponding unrestricted pointer. | ||
| 637 | /// Uses the `ty_op` field. | ||
| 638 | unwrap_restricted, | ||
| 639 | /// Converts a runtime restricted pointer into the corresponding unrestricted pointer. | ||
| 640 | /// All invalid pointers are a guaranteed safety panic, which is only applicable | ||
| 641 | /// when the restricted pointer type belongs to a module with safety enabled. | ||
| 642 | /// The panic handler function must be populated before lowering AIR | ||
| 643 | /// that contains this instruction. | ||
| 644 | /// Uses the `ty_op` field. | ||
| 645 | unwrap_restricted_safe, | ||
| 636 | /// Given a pointer to a struct or union and a field index, returns a pointer to the field. | 646 | /// Given a pointer to a struct or union and a field index, returns a pointer to the field. |
| 637 | /// Uses the `ty_pl` field, payload is `StructField`. | 647 | /// Uses the `ty_pl` field, payload is `StructField`. |
| 638 | /// TODO rename to `agg_field_ptr`. | 648 | /// TODO rename to `agg_field_ptr`. |
| ... | @@ -1681,6 +1691,8 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1681,6 +1691,8 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1681 | .unwrap_errunion_err_ptr, | 1691 | .unwrap_errunion_err_ptr, |
| 1682 | .wrap_errunion_payload, | 1692 | .wrap_errunion_payload, |
| 1683 | .wrap_errunion_err, | 1693 | .wrap_errunion_err, |
| 1694 | .unwrap_restricted, | ||
| 1695 | .unwrap_restricted_safe, | ||
| 1684 | .slice_ptr, | 1696 | .slice_ptr, |
| 1685 | .ptr_slice_len_ptr, | 1697 | .ptr_slice_len_ptr, |
| 1686 | .ptr_slice_ptr_ptr, | 1698 | .ptr_slice_ptr_ptr, |
| ... | @@ -1886,6 +1898,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { | ... | @@ -1886,6 +1898,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1886 | .unreach, | 1898 | .unreach, |
| 1887 | .optional_payload_ptr_set, | 1899 | .optional_payload_ptr_set, |
| 1888 | .errunion_payload_ptr_set, | 1900 | .errunion_payload_ptr_set, |
| 1901 | .unwrap_restricted_safe, | ||
| 1889 | .set_union_tag, | 1902 | .set_union_tag, |
| 1890 | .memset, | 1903 | .memset, |
| 1891 | .memset_safe, | 1904 | .memset_safe, |
| ... | @@ -2014,6 +2027,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { | ... | @@ -2014,6 +2027,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 2014 | .unwrap_errunion_payload_ptr, | 2027 | .unwrap_errunion_payload_ptr, |
| 2015 | .wrap_errunion_payload, | 2028 | .wrap_errunion_payload, |
| 2016 | .wrap_errunion_err, | 2029 | .wrap_errunion_err, |
| 2030 | .unwrap_restricted, | ||
| 2017 | .struct_field_ptr, | 2031 | .struct_field_ptr, |
| 2018 | .struct_field_ptr_index_0, | 2032 | .struct_field_ptr_index_0, |
| 2019 | .struct_field_ptr_index_1, | 2033 | .struct_field_ptr_index_1, |
src/Air/Legalize.zig+2| ... | @@ -741,6 +741,8 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { | ... | @@ -741,6 +741,8 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { |
| 741 | .errunion_payload_ptr_set, | 741 | .errunion_payload_ptr_set, |
| 742 | .wrap_errunion_payload, | 742 | .wrap_errunion_payload, |
| 743 | .wrap_errunion_err, | 743 | .wrap_errunion_err, |
| 744 | .unwrap_restricted, | ||
| 745 | .unwrap_restricted_safe, | ||
| 744 | .struct_field_ptr, | 746 | .struct_field_ptr, |
| 745 | .struct_field_ptr_index_0, | 747 | .struct_field_ptr_index_0, |
| 746 | .struct_field_ptr_index_1, | 748 | .struct_field_ptr_index_1, |
src/Air/Liveness.zig+2| ... | @@ -506,6 +506,8 @@ fn analyzeInst( | ... | @@ -506,6 +506,8 @@ fn analyzeInst( |
| 506 | .unwrap_errunion_err_ptr, | 506 | .unwrap_errunion_err_ptr, |
| 507 | .wrap_errunion_payload, | 507 | .wrap_errunion_payload, |
| 508 | .wrap_errunion_err, | 508 | .wrap_errunion_err, |
| 509 | .unwrap_restricted, | ||
| 510 | .unwrap_restricted_safe, | ||
| 509 | .slice_ptr, | 511 | .slice_ptr, |
| 510 | .slice_len, | 512 | .slice_len, |
| 511 | .ptr_slice_len_ptr, | 513 | .ptr_slice_len_ptr, |
src/Air/Liveness/Verify.zig+2| ... | @@ -96,6 +96,8 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -96,6 +96,8 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 96 | .unwrap_errunion_err_ptr, | 96 | .unwrap_errunion_err_ptr, |
| 97 | .wrap_errunion_payload, | 97 | .wrap_errunion_payload, |
| 98 | .wrap_errunion_err, | 98 | .wrap_errunion_err, |
| 99 | .unwrap_restricted, | ||
| 100 | .unwrap_restricted_safe, | ||
| 99 | .slice_ptr, | 101 | .slice_ptr, |
| 100 | .slice_len, | 102 | .slice_len, |
| 101 | .ptr_slice_len_ptr, | 103 | .ptr_slice_len_ptr, |
src/Air/print.zig+2| ... | @@ -250,6 +250,8 @@ const Writer = struct { | ... | @@ -250,6 +250,8 @@ const Writer = struct { |
| 250 | .unwrap_errunion_err_ptr, | 250 | .unwrap_errunion_err_ptr, |
| 251 | .wrap_errunion_payload, | 251 | .wrap_errunion_payload, |
| 252 | .wrap_errunion_err, | 252 | .wrap_errunion_err, |
| 253 | .unwrap_restricted, | ||
| 254 | .unwrap_restricted_safe, | ||
| 253 | .slice_ptr, | 255 | .slice_ptr, |
| 254 | .slice_len, | 256 | .slice_len, |
| 255 | .ptr_slice_len_ptr, | 257 | .ptr_slice_len_ptr, |
src/InternPool.zig+176-54| ... | @@ -1969,6 +1969,7 @@ pub const CaptureValue = packed struct(u32) { | ... | @@ -1969,6 +1969,7 @@ pub const CaptureValue = packed struct(u32) { |
| 1969 | pub const Key = union(enum) { | 1969 | pub const Key = union(enum) { |
| 1970 | int_type: IntType, | 1970 | int_type: IntType, |
| 1971 | ptr_type: PtrType, | 1971 | ptr_type: PtrType, |
| 1972 | restricted_ptr_type: RestrictedPtrType, | ||
| 1972 | array_type: ArrayType, | 1973 | array_type: ArrayType, |
| 1973 | vector_type: VectorType, | 1974 | vector_type: VectorType, |
| 1974 | opt_type: Index, | 1975 | opt_type: Index, |
| ... | @@ -2094,6 +2095,14 @@ pub const Key = union(enum) { | ... | @@ -2094,6 +2095,14 @@ pub const Key = union(enum) { |
| 2094 | pub const AddressSpace = std.builtin.AddressSpace; | 2095 | pub const AddressSpace = std.builtin.AddressSpace; |
| 2095 | }; | 2096 | }; |
| 2096 | 2097 | ||
| 2098 | /// Extern layout so it can be hashed with `std.mem.asBytes`. | ||
| 2099 | pub const RestrictedPtrType = extern struct { | ||
| 2100 | /// A `reify_restricted` instruction. | ||
| 2101 | zir_index: TrackedInst.Index, | ||
| 2102 | /// The underlying pointer type. | ||
| 2103 | unrestricted_ptr_type: Index, | ||
| 2104 | }; | ||
| 2105 | |||
| 2097 | /// Extern so that hashing can be done via memory reinterpreting. | 2106 | /// Extern so that hashing can be done via memory reinterpreting. |
| 2098 | pub const ArrayType = extern struct { | 2107 | pub const ArrayType = extern struct { |
| 2099 | len: u64, | 2108 | len: u64, |
| ... | @@ -2590,6 +2599,7 @@ pub const Key = union(enum) { | ... | @@ -2590,6 +2599,7 @@ pub const Key = union(enum) { |
| 2590 | return switch (key) { | 2599 | return switch (key) { |
| 2591 | // TODO: assert no padding in these types | 2600 | // TODO: assert no padding in these types |
| 2592 | inline .ptr_type, | 2601 | inline .ptr_type, |
| 2602 | .restricted_ptr_type, | ||
| 2593 | .array_type, | 2603 | .array_type, |
| 2594 | .vector_type, | 2604 | .vector_type, |
| 2595 | .opt_type, | 2605 | .opt_type, |
| ... | @@ -2606,11 +2616,11 @@ pub const Key = union(enum) { | ... | @@ -2606,11 +2616,11 @@ pub const Key = union(enum) { |
| 2606 | .un, | 2616 | .un, |
| 2607 | => |x| Hash.hash(seed, asBytes(&x)), | 2617 | => |x| Hash.hash(seed, asBytes(&x)), |
| 2608 | 2618 | ||
| 2609 | .int_type => |x| Hash.hash(seed + @intFromEnum(x.signedness), asBytes(&x.bits)), | 2619 | .int_type => |x| Hash.hash(seed | @shlExact(@as(u64, @intFromEnum(x.signedness)), 63), asBytes(&x.bits)), |
| 2610 | 2620 | ||
| 2611 | .error_union => |x| switch (x.val) { | 2621 | .error_union => |x| switch (x.val) { |
| 2612 | .err_name => |y| Hash.hash(seed + 0, asBytes(&x.ty) ++ asBytes(&y)), | 2622 | .err_name => |y| Hash.hash(seed | @as(u64, 0 << 63), asBytes(&x.ty) ++ asBytes(&y)), |
| 2613 | .payload => |y| Hash.hash(seed + 1, asBytes(&x.ty) ++ asBytes(&y)), | 2623 | .payload => |y| Hash.hash(seed | @as(u64, 1 << 63), asBytes(&x.ty) ++ asBytes(&y)), |
| 2614 | }, | 2624 | }, |
| 2615 | 2625 | ||
| 2616 | .opaque_type, | 2626 | .opaque_type, |
| ... | @@ -2631,10 +2641,7 @@ pub const Key = union(enum) { | ... | @@ -2631,10 +2641,7 @@ pub const Key = union(enum) { |
| 2631 | std.hash.autoHash(&hasher, cv); | 2641 | std.hash.autoHash(&hasher, cv); |
| 2632 | } | 2642 | } |
| 2633 | }, | 2643 | }, |
| 2634 | .reified => |reified| { | 2644 | .reified => |reified| std.hash.autoHash(&hasher, reified), |
| 2635 | std.hash.autoHash(&hasher, reified.zir_index); | ||
| 2636 | std.hash.autoHash(&hasher, reified.type_hash); | ||
| 2637 | }, | ||
| 2638 | .generated_union_tag => |union_type| { | 2645 | .generated_union_tag => |union_type| { |
| 2639 | std.hash.autoHash(&hasher, union_type); | 2646 | std.hash.autoHash(&hasher, union_type); |
| 2640 | }, | 2647 | }, |
| ... | @@ -2672,7 +2679,7 @@ pub const Key = union(enum) { | ... | @@ -2672,7 +2679,7 @@ pub const Key = union(enum) { |
| 2672 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. | 2679 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. |
| 2673 | // This is sound due to pointer provenance rules. | 2680 | // This is sound due to pointer provenance rules. |
| 2674 | const addr_tag: Key.Ptr.BaseAddr.Tag = ptr.base_addr; | 2681 | const addr_tag: Key.Ptr.BaseAddr.Tag = ptr.base_addr; |
| 2675 | const seed2 = seed + @intFromEnum(addr_tag); | 2682 | const seed2 = seed | @shlExact(@as(u64, @intFromEnum(addr_tag)), 60); |
| 2676 | const big_offset: i128 = ptr.byte_offset; | 2683 | const big_offset: i128 = ptr.byte_offset; |
| 2677 | const common = asBytes(&ptr.ty) ++ asBytes(&big_offset); | 2684 | const common = asBytes(&ptr.ty) ++ asBytes(&big_offset); |
| 2678 | return switch (ptr.base_addr) { | 2685 | return switch (ptr.base_addr) { |
| ... | @@ -3020,6 +3027,8 @@ pub const Key = union(enum) { | ... | @@ -3020,6 +3027,8 @@ pub const Key = union(enum) { |
| 3020 | } | 3027 | } |
| 3021 | }, | 3028 | }, |
| 3022 | 3029 | ||
| 3030 | .restricted_ptr_type => |a_r| return std.meta.eql(a_r, b.restricted_ptr_type), | ||
| 3031 | |||
| 3023 | inline .opaque_type, .enum_type, .union_type, .struct_type => |a_info, a_tag_ct| { | 3032 | inline .opaque_type, .enum_type, .union_type, .struct_type => |a_info, a_tag_ct| { |
| 3024 | const b_info = @field(b, @tagName(a_tag_ct)); | 3033 | const b_info = @field(b, @tagName(a_tag_ct)); |
| 3025 | if (std.meta.activeTag(a_info) != b_info) return false; | 3034 | if (std.meta.activeTag(a_info) != b_info) return false; |
| ... | @@ -3037,11 +3046,7 @@ pub const Key = union(enum) { | ... | @@ -3037,11 +3046,7 @@ pub const Key = union(enum) { |
| 3037 | }; | 3046 | }; |
| 3038 | return std.mem.eql(u32, @ptrCast(a_captures), @ptrCast(b_captures)); | 3047 | return std.mem.eql(u32, @ptrCast(a_captures), @ptrCast(b_captures)); |
| 3039 | }, | 3048 | }, |
| 3040 | .reified => |a_r| { | 3049 | .reified => |a_r| return std.meta.eql(a_r, b_info.reified), |
| 3041 | const b_r = b_info.reified; | ||
| 3042 | return a_r.zir_index == b_r.zir_index and | ||
| 3043 | a_r.type_hash == b_r.type_hash; | ||
| 3044 | }, | ||
| 3045 | .generated_union_tag => |a_union_ty| return a_union_ty == b_info.generated_union_tag, | 3050 | .generated_union_tag => |a_union_ty| return a_union_ty == b_info.generated_union_tag, |
| 3046 | } | 3051 | } |
| 3047 | }, | 3052 | }, |
| ... | @@ -3125,6 +3130,7 @@ pub const Key = union(enum) { | ... | @@ -3125,6 +3130,7 @@ pub const Key = union(enum) { |
| 3125 | return switch (key) { | 3130 | return switch (key) { |
| 3126 | .int_type, | 3131 | .int_type, |
| 3127 | .ptr_type, | 3132 | .ptr_type, |
| 3133 | .restricted_ptr_type, | ||
| 3128 | .array_type, | 3134 | .array_type, |
| 3129 | .vector_type, | 3135 | .vector_type, |
| 3130 | .opt_type, | 3136 | .opt_type, |
| ... | @@ -3172,6 +3178,8 @@ pub const Key = union(enum) { | ... | @@ -3172,6 +3178,8 @@ pub const Key = union(enum) { |
| 3172 | } | 3178 | } |
| 3173 | }; | 3179 | }; |
| 3174 | 3180 | ||
| 3181 | pub const LoadedRestrictedType = Tag.TypeRestricted; | ||
| 3182 | |||
| 3175 | pub const LoadedStructType = struct { | 3183 | pub const LoadedStructType = struct { |
| 3176 | /// Index of the `struct_decl` or `reify` ZIR instruction. | 3184 | /// Index of the `struct_decl` or `reify` ZIR instruction. |
| 3177 | zir_index: TrackedInst.Index, | 3185 | zir_index: TrackedInst.Index, |
| ... | @@ -3499,6 +3507,12 @@ pub const LoadedOpaqueType = struct { | ... | @@ -3499,6 +3507,12 @@ pub const LoadedOpaqueType = struct { |
| 3499 | namespace: NamespaceIndex, | 3507 | namespace: NamespaceIndex, |
| 3500 | }; | 3508 | }; |
| 3501 | 3509 | ||
| 3510 | pub fn loadRestrictedType(ip: *const InternPool, index: Index) LoadedRestrictedType { | ||
| 3511 | const unwrapped_index = index.unwrap(ip); | ||
| 3512 | const item = unwrapped_index.getItem(ip); | ||
| 3513 | return extraData(unwrapped_index.getExtra(ip), Tag.TypeRestricted, item.data); | ||
| 3514 | } | ||
| 3515 | |||
| 3502 | pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { | 3516 | pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3503 | const unwrapped_index = index.unwrap(ip); | 3517 | const unwrapped_index = index.unwrap(ip); |
| 3504 | const extra_list = unwrapped_index.getExtra(ip); | 3518 | const extra_list = unwrapped_index.getExtra(ip); |
| ... | @@ -4173,6 +4187,7 @@ pub const Index = enum(u32) { | ... | @@ -4173,6 +4187,7 @@ pub const Index = enum(u32) { |
| 4173 | type_array_small: struct { data: *Vector }, | 4187 | type_array_small: struct { data: *Vector }, |
| 4174 | type_vector: struct { data: *Vector }, | 4188 | type_vector: struct { data: *Vector }, |
| 4175 | type_pointer: struct { data: *Tag.TypePointer }, | 4189 | type_pointer: struct { data: *Tag.TypePointer }, |
| 4190 | type_restricted: struct { data: *Tag.TypeRestricted }, | ||
| 4176 | type_slice: DataIsIndex, | 4191 | type_slice: DataIsIndex, |
| 4177 | type_optional: DataIsIndex, | 4192 | type_optional: DataIsIndex, |
| 4178 | type_anyframe: DataIsIndex, | 4193 | type_anyframe: DataIsIndex, |
| ... | @@ -4771,6 +4786,9 @@ pub const Tag = enum(u8) { | ... | @@ -4771,6 +4786,9 @@ pub const Tag = enum(u8) { |
| 4771 | /// A slice type. | 4786 | /// A slice type. |
| 4772 | /// data is Index of underlying pointer type. | 4787 | /// data is Index of underlying pointer type. |
| 4773 | type_slice, | 4788 | type_slice, |
| 4789 | /// A restricted pointer type. | ||
| 4790 | /// data is payload to `TypeRestricted`. | ||
| 4791 | type_restricted, | ||
| 4774 | /// An optional type. | 4792 | /// An optional type. |
| 4775 | /// data is the child type. | 4793 | /// data is the child type. |
| 4776 | type_optional, | 4794 | type_optional, |
| ... | @@ -5024,13 +5042,6 @@ pub const Tag = enum(u8) { | ... | @@ -5024,13 +5042,6 @@ pub const Tag = enum(u8) { |
| 5024 | /// data is extra index to `MemoizedCall` | 5042 | /// data is extra index to `MemoizedCall` |
| 5025 | memoized_call, | 5043 | memoized_call, |
| 5026 | 5044 | ||
| 5027 | const ErrorUnionType = Key.ErrorUnionType; | ||
| 5028 | const TypeValue = Key.TypeValue; | ||
| 5029 | const Error = Key.Error; | ||
| 5030 | const EnumTag = Key.EnumTag; | ||
| 5031 | const Union = Key.Union; | ||
| 5032 | const TypePointer = Key.PtrType; | ||
| 5033 | |||
| 5034 | const struct_packed_encoding = .{ | 5045 | const struct_packed_encoding = .{ |
| 5035 | .summary = .@"{.payload.name%summary#\"}", | 5046 | .summary = .@"{.payload.name%summary#\"}", |
| 5036 | .payload = TypeStructPacked, | 5047 | .payload = TypeStructPacked, |
| ... | @@ -5116,6 +5127,7 @@ pub const Tag = enum(u8) { | ... | @@ -5116,6 +5127,7 @@ pub const Tag = enum(u8) { |
| 5116 | .type_array_small = .{ .summary = .@"[{.payload.len%value}]{.payload.child%summary}", .payload = Vector }, | 5127 | .type_array_small = .{ .summary = .@"[{.payload.len%value}]{.payload.child%summary}", .payload = Vector }, |
| 5117 | .type_vector = .{ .summary = .@"@Vector({.payload.len%value}, {.payload.child%summary})", .payload = Vector }, | 5128 | .type_vector = .{ .summary = .@"@Vector({.payload.len%value}, {.payload.child%summary})", .payload = Vector }, |
| 5118 | .type_pointer = .{ .summary = .@"*... {.payload.child%summary}", .payload = TypePointer }, | 5129 | .type_pointer = .{ .summary = .@"*... {.payload.child%summary}", .payload = TypePointer }, |
| 5130 | .type_restricted = .{ .summary = .@"@Restricted({.payload.ptr_type%summary})", .payload = TypeRestricted }, | ||
| 5119 | .type_slice = .{ .summary = .@"[]... {.data.unwrapped.payload.child%summary}", .data = Index }, | 5131 | .type_slice = .{ .summary = .@"[]... {.data.unwrapped.payload.child%summary}", .data = Index }, |
| 5120 | .type_optional = .{ .summary = .@"?{.data%summary}", .data = Index }, | 5132 | .type_optional = .{ .summary = .@"?{.data%summary}", .data = Index }, |
| 5121 | .type_anyframe = .{ .summary = .@"anyframe->{.data%summary}", .data = Index }, | 5133 | .type_anyframe = .{ .summary = .@"anyframe->{.data%summary}", .data = Index }, |
| ... | @@ -5363,6 +5375,25 @@ pub const Tag = enum(u8) { | ... | @@ -5363,6 +5375,25 @@ pub const Tag = enum(u8) { |
| 5363 | return @field(encodings, @tagName(tag)).payload; | 5375 | return @field(encodings, @tagName(tag)).payload; |
| 5364 | } | 5376 | } |
| 5365 | 5377 | ||
| 5378 | const ErrorUnionType = Key.ErrorUnionType; | ||
| 5379 | const TypeValue = Key.TypeValue; | ||
| 5380 | const Error = Key.Error; | ||
| 5381 | const EnumTag = Key.EnumTag; | ||
| 5382 | const Union = Key.Union; | ||
| 5383 | const TypePointer = Key.PtrType; | ||
| 5384 | |||
| 5385 | const TypeRestricted = struct { | ||
| 5386 | /// Index of the `reify_restricted` ZIR instruction. | ||
| 5387 | zir_index: TrackedInst.Index, | ||
| 5388 | |||
| 5389 | // TODO: the non-fqn will be needed by the new dwarf structure | ||
| 5390 | /// The name of this restricted type. | ||
| 5391 | name: NullTerminatedString, | ||
| 5392 | |||
| 5393 | /// The pointer type this restricted type is based on. | ||
| 5394 | unrestricted_ptr_type: Index, | ||
| 5395 | }; | ||
| 5396 | |||
| 5366 | pub const Extern = struct { | 5397 | pub const Extern = struct { |
| 5367 | // name, is_const, alignment, addrspace come from `owner_nav`. | 5398 | // name, is_const, alignment, addrspace come from `owner_nav`. |
| 5368 | ty: Index, | 5399 | ty: Index, |
| ... | @@ -6455,6 +6486,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -6455,6 +6486,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6455 | return .{ .ptr_type = ptr_info }; | 6486 | return .{ .ptr_type = ptr_info }; |
| 6456 | }, | 6487 | }, |
| 6457 | 6488 | ||
| 6489 | .type_restricted => { | ||
| 6490 | const restricted_ptr_info = extraData(unwrapped_index.getExtra(ip), Tag.TypeRestricted, data); | ||
| 6491 | return .{ .restricted_ptr_type = .{ | ||
| 6492 | .zir_index = restricted_ptr_info.zir_index, | ||
| 6493 | .unrestricted_ptr_type = restricted_ptr_info.unrestricted_ptr_type, | ||
| 6494 | } }; | ||
| 6495 | }, | ||
| 6496 | |||
| 6458 | .type_optional => .{ .opt_type = @enumFromInt(data) }, | 6497 | .type_optional => .{ .opt_type = @enumFromInt(data) }, |
| 6459 | .type_anyframe => .{ .anyframe_type = @enumFromInt(data) }, | 6498 | .type_anyframe => .{ .anyframe_type = @enumFromInt(data) }, |
| 6460 | 6499 | ||
| ... | @@ -7237,6 +7276,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: | ... | @@ -7237,6 +7276,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7237 | .data = try addExtra(extra, ptr_type_adjusted), | 7276 | .data = try addExtra(extra, ptr_type_adjusted), |
| 7238 | }); | 7277 | }); |
| 7239 | }, | 7278 | }, |
| 7279 | .restricted_ptr_type => unreachable, // instead getReifiedRestrictedType | ||
| 7240 | .array_type => |array_type| { | 7280 | .array_type => |array_type| { |
| 7241 | assert(array_type.child != .none); | 7281 | assert(array_type.child != .none); |
| 7242 | assert(array_type.sentinel == .none or ip.typeOf(array_type.sentinel) == array_type.child); | 7282 | assert(array_type.sentinel == .none or ip.typeOf(array_type.sentinel) == array_type.child); |
| ... | @@ -7367,7 +7407,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: | ... | @@ -7367,7 +7407,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7367 | }, | 7407 | }, |
| 7368 | 7408 | ||
| 7369 | .ptr => |ptr| { | 7409 | .ptr => |ptr| { |
| 7370 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; | 7410 | const ptr_type = switch (ip.indexToKey(ptr.ty)) { |
| 7411 | .ptr_type => |ptr_type| ptr_type, | ||
| 7412 | .restricted_ptr_type => |restricted_ptr_type| ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 7413 | else => unreachable, | ||
| 7414 | }; | ||
| 7371 | assert(ptr_type.flags.size != .slice); | 7415 | assert(ptr_type.flags.size != .slice); |
| 7372 | items.appendAssumeCapacity(switch (ptr.base_addr) { | 7416 | items.appendAssumeCapacity(switch (ptr.base_addr) { |
| 7373 | .nav => |nav| .{ | 7417 | .nav => |nav| .{ |
| ... | @@ -7959,6 +8003,65 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: | ... | @@ -7959,6 +8003,65 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7959 | return gop.put(); | 8003 | return gop.put(); |
| 7960 | } | 8004 | } |
| 7961 | 8005 | ||
| 8006 | pub fn getReifiedRestrictedType( | ||
| 8007 | ip: *InternPool, | ||
| 8008 | gpa: Allocator, | ||
| 8009 | io: Io, | ||
| 8010 | tid: Zcu.PerThread.Id, | ||
| 8011 | zir_index: TrackedInst.Index, | ||
| 8012 | unrestricted_ptr_type: Index, | ||
| 8013 | ) Allocator.Error!WipRestrictedType.Result { | ||
| 8014 | var gop = try ip.getOrPutKey(gpa, io, tid, .{ .restricted_ptr_type = .{ | ||
| 8015 | .zir_index = zir_index, | ||
| 8016 | .unrestricted_ptr_type = unrestricted_ptr_type, | ||
| 8017 | } }); | ||
| 8018 | defer gop.deinit(); | ||
| 8019 | if (gop == .existing) return .{ .existing = gop.existing }; | ||
| 8020 | |||
| 8021 | const local = ip.getLocal(tid); | ||
| 8022 | const items = local.getMutableItems(gpa, io); | ||
| 8023 | const extra = local.getMutableExtra(gpa, io); | ||
| 8024 | try items.ensureUnusedCapacity(1); | ||
| 8025 | |||
| 8026 | try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeRestricted).@"struct".fields.len); | ||
| 8027 | |||
| 8028 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeRestricted{ | ||
| 8029 | .zir_index = zir_index, | ||
| 8030 | .name = undefined, | ||
| 8031 | .unrestricted_ptr_type = unrestricted_ptr_type, | ||
| 8032 | }); | ||
| 8033 | items.appendAssumeCapacity(.{ | ||
| 8034 | .tag = .type_restricted, | ||
| 8035 | .data = extra_index, | ||
| 8036 | }); | ||
| 8037 | return .{ .wip = .{ | ||
| 8038 | .index = gop.put(), | ||
| 8039 | .tid = tid, | ||
| 8040 | .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeRestricted, "name").?, | ||
| 8041 | } }; | ||
| 8042 | } | ||
| 8043 | |||
| 8044 | pub const WipRestrictedType = struct { | ||
| 8045 | index: Index, | ||
| 8046 | tid: Zcu.PerThread.Id, | ||
| 8047 | type_name_index: u32, | ||
| 8048 | |||
| 8049 | pub fn setName(wip: WipRestrictedType, ip: *InternPool, type_name: NullTerminatedString) void { | ||
| 8050 | const extra = ip.getLocalShared(wip.tid).extra.acquire(); | ||
| 8051 | const extra_items = extra.view().items(.@"0"); | ||
| 8052 | extra_items[wip.type_name_index] = @intFromEnum(type_name); | ||
| 8053 | } | ||
| 8054 | |||
| 8055 | pub fn cancel(wip: WipRestrictedType, ip: *InternPool, tid: Zcu.PerThread.Id) void { | ||
| 8056 | ip.remove(tid, wip.index); | ||
| 8057 | } | ||
| 8058 | |||
| 8059 | pub const Result = union(enum) { | ||
| 8060 | wip: WipRestrictedType, | ||
| 8061 | existing: Index, | ||
| 8062 | }; | ||
| 8063 | }; | ||
| 8064 | |||
| 7962 | pub fn getDeclaredStructType( | 8065 | pub fn getDeclaredStructType( |
| 7963 | ip: *InternPool, | 8066 | ip: *InternPool, |
| 7964 | gpa: Allocator, | 8067 | gpa: Allocator, |
| ... | @@ -9925,6 +10028,7 @@ test "basic usage" { | ... | @@ -9925,6 +10028,7 @@ test "basic usage" { |
| 9925 | pub fn childType(ip: *const InternPool, i: Index) Index { | 10028 | pub fn childType(ip: *const InternPool, i: Index) Index { |
| 9926 | return switch (ip.indexToKey(i)) { | 10029 | return switch (ip.indexToKey(i)) { |
| 9927 | .ptr_type => |ptr_type| ptr_type.child, | 10030 | .ptr_type => |ptr_type| ptr_type.child, |
| 10031 | .restricted_ptr_type => |restricted_ptr_type| ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type.child, | ||
| 9928 | .vector_type => |vector_type| vector_type.child, | 10032 | .vector_type => |vector_type| vector_type.child, |
| 9929 | .array_type => |array_type| array_type.child, | 10033 | .array_type => |array_type| array_type.child, |
| 9930 | .opt_type, .anyframe_type => |child| child, | 10034 | .opt_type, .anyframe_type => |child| child, |
| ... | @@ -10007,22 +10111,28 @@ pub fn getCoerced( | ... | @@ -10007,22 +10111,28 @@ pub fn getCoerced( |
| 10007 | .val = .none, | 10111 | .val = .none, |
| 10008 | } }); | 10112 | } }); |
| 10009 | 10113 | ||
| 10010 | if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) { | 10114 | new_ty: switch (ip.indexToKey(new_ty)) { |
| 10011 | .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{ | 10115 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 10012 | .ty = new_ty, | 10116 | .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{ |
| 10013 | .base_addr = .int, | 10117 | .ty = new_ty, |
| 10014 | .byte_offset = 0, | ||
| 10015 | } }), | ||
| 10016 | .slice => return ip.get(gpa, io, tid, .{ .slice = .{ | ||
| 10017 | .ty = new_ty, | ||
| 10018 | .ptr = try ip.get(gpa, io, tid, .{ .ptr = .{ | ||
| 10019 | .ty = ip.slicePtrType(new_ty), | ||
| 10020 | .base_addr = .int, | 10118 | .base_addr = .int, |
| 10021 | .byte_offset = 0, | 10119 | .byte_offset = 0, |
| 10022 | } }), | 10120 | } }), |
| 10023 | .len = .undef_usize, | 10121 | .slice => return ip.get(gpa, io, tid, .{ .slice = .{ |
| 10024 | } }), | 10122 | .ty = new_ty, |
| 10025 | }; | 10123 | .ptr = try ip.get(gpa, io, tid, .{ .ptr = .{ |
| 10124 | .ty = ip.slicePtrType(new_ty), | ||
| 10125 | .base_addr = .int, | ||
| 10126 | .byte_offset = 0, | ||
| 10127 | } }), | ||
| 10128 | .len = .undef_usize, | ||
| 10129 | } }), | ||
| 10130 | }, | ||
| 10131 | .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{ | ||
| 10132 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 10133 | }, | ||
| 10134 | else => {}, | ||
| 10135 | } | ||
| 10026 | }, | 10136 | }, |
| 10027 | else => { | 10137 | else => { |
| 10028 | const unwrapped_val = val.unwrap(ip); | 10138 | const unwrapped_val = val.unwrap(ip); |
| ... | @@ -10101,28 +10211,40 @@ pub fn getCoerced( | ... | @@ -10101,28 +10211,40 @@ pub fn getCoerced( |
| 10101 | }, | 10211 | }, |
| 10102 | else => {}, | 10212 | else => {}, |
| 10103 | }, | 10213 | }, |
| 10104 | .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .slice) | 10214 | .slice => |slice| new_ty: switch (ip.indexToKey(new_ty)) { |
| 10105 | return ip.get(gpa, io, tid, .{ .slice = .{ | 10215 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 10106 | .ty = new_ty, | 10216 | .one, .many, .c => {}, |
| 10107 | .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)), | 10217 | .slice => return ip.get(gpa, io, tid, .{ .slice = .{ |
| 10108 | .len = slice.len, | 10218 | .ty = new_ty, |
| 10109 | } }) | 10219 | .ptr = try ip.getCoerced(gpa, io, tid, slice.ptr, ip.slicePtrType(new_ty)), |
| 10110 | else if (ip.isIntegerType(new_ty)) | 10220 | .len = slice.len, |
| 10111 | return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty), | 10221 | } }), |
| 10112 | .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .slice) | 10222 | }, |
| 10113 | return ip.get(gpa, io, tid, .{ .ptr = .{ | 10223 | .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{ |
| 10114 | .ty = new_ty, | 10224 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, |
| 10115 | .base_addr = ptr.base_addr, | 10225 | }, |
| 10116 | .byte_offset = ptr.byte_offset, | 10226 | else => if (ip.isIntegerType(new_ty)) return ip.getCoerced(gpa, io, tid, slice.ptr, new_ty), |
| 10117 | } }) | 10227 | }, |
| 10118 | else if (ip.isIntegerType(new_ty)) | 10228 | .ptr => |ptr| new_ty: switch (ip.indexToKey(new_ty)) { |
| 10119 | switch (ptr.base_addr) { | 10229 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 10230 | .one, .many, .c => return ip.get(gpa, io, tid, .{ .ptr = .{ | ||
| 10231 | .ty = new_ty, | ||
| 10232 | .base_addr = ptr.base_addr, | ||
| 10233 | .byte_offset = ptr.byte_offset, | ||
| 10234 | } }), | ||
| 10235 | .slice => {}, | ||
| 10236 | }, | ||
| 10237 | .restricted_ptr_type => |restricted_ptr_type| continue :new_ty .{ | ||
| 10238 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 10239 | }, | ||
| 10240 | else => if (ip.isIntegerType(new_ty)) switch (ptr.base_addr) { | ||
| 10120 | .int => return ip.get(gpa, io, tid, .{ .int = .{ | 10241 | .int => return ip.get(gpa, io, tid, .{ .int = .{ |
| 10121 | .ty = .usize_type, | 10242 | .ty = .usize_type, |
| 10122 | .storage = .{ .u64 = @intCast(ptr.byte_offset) }, | 10243 | .storage = .{ .u64 = @intCast(ptr.byte_offset) }, |
| 10123 | } }), | 10244 | } }), |
| 10124 | else => {}, | 10245 | else => {}, |
| 10125 | }, | 10246 | }, |
| 10247 | }, | ||
| 10126 | .opt => |opt| switch (ip.indexToKey(new_ty)) { | 10248 | .opt => |opt| switch (ip.indexToKey(new_ty)) { |
| 10127 | .ptr_type => |ptr_type| return switch (opt.val) { | 10249 | .ptr_type => |ptr_type| return switch (opt.val) { |
| 10128 | .none => switch (ptr_type.flags.size) { | 10250 | .none => switch (ptr_type.flags.size) { |
| ... | @@ -10397,10 +10519,6 @@ pub fn isFunctionType(ip: *const InternPool, ty: Index) bool { | ... | @@ -10397,10 +10519,6 @@ pub fn isFunctionType(ip: *const InternPool, ty: Index) bool { |
| 10397 | return ip.indexToKey(ty) == .func_type; | 10519 | return ip.indexToKey(ty) == .func_type; |
| 10398 | } | 10520 | } |
| 10399 | 10521 | ||
| 10400 | pub fn isPointerType(ip: *const InternPool, ty: Index) bool { | ||
| 10401 | return ip.indexToKey(ty) == .ptr_type; | ||
| 10402 | } | ||
| 10403 | |||
| 10404 | pub fn isOptionalType(ip: *const InternPool, ty: Index) bool { | 10522 | pub fn isOptionalType(ip: *const InternPool, ty: Index) bool { |
| 10405 | return ip.indexToKey(ty) == .opt_type; | 10523 | return ip.indexToKey(ty) == .opt_type; |
| 10406 | } | 10524 | } |
| ... | @@ -10577,6 +10695,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo | ... | @@ -10577,6 +10695,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10577 | .type_array_big => @sizeOf(Array), | 10695 | .type_array_big => @sizeOf(Array), |
| 10578 | .type_vector => @sizeOf(Vector), | 10696 | .type_vector => @sizeOf(Vector), |
| 10579 | .type_pointer => @sizeOf(Tag.TypePointer), | 10697 | .type_pointer => @sizeOf(Tag.TypePointer), |
| 10698 | .type_restricted => @sizeOf(Tag.TypeRestricted), | ||
| 10580 | .type_slice => 0, | 10699 | .type_slice => 0, |
| 10581 | .type_optional => 0, | 10700 | .type_optional => 0, |
| 10582 | .type_anyframe => 0, | 10701 | .type_anyframe => 0, |
| ... | @@ -10838,6 +10957,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { | ... | @@ -10838,6 +10957,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { |
| 10838 | .type_array_big, | 10957 | .type_array_big, |
| 10839 | .type_vector, | 10958 | .type_vector, |
| 10840 | .type_pointer, | 10959 | .type_pointer, |
| 10960 | .type_restricted, | ||
| 10841 | .type_optional, | 10961 | .type_optional, |
| 10842 | .type_anyframe, | 10962 | .type_anyframe, |
| 10843 | .type_error_union, | 10963 | .type_error_union, |
| ... | @@ -11576,6 +11696,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { | ... | @@ -11576,6 +11696,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11576 | .type_array_small, | 11696 | .type_array_small, |
| 11577 | .type_vector, | 11697 | .type_vector, |
| 11578 | .type_pointer, | 11698 | .type_pointer, |
| 11699 | .type_restricted, | ||
| 11579 | .type_slice, | 11700 | .type_slice, |
| 11580 | .type_optional, | 11701 | .type_optional, |
| 11581 | .type_anyframe, | 11702 | .type_anyframe, |
| ... | @@ -11921,6 +12042,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { | ... | @@ -11921,6 +12042,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 11921 | 12042 | ||
| 11922 | .type_pointer, | 12043 | .type_pointer, |
| 11923 | .type_slice, | 12044 | .type_slice, |
| 12045 | .type_restricted, | ||
| 11924 | => .pointer, | 12046 | => .pointer, |
| 11925 | 12047 | ||
| 11926 | .type_optional => .optional, | 12048 | .type_optional => .optional, |
src/Sema.zig+197-34| ... | @@ -398,7 +398,7 @@ pub const Block = struct { | ... | @@ -398,7 +398,7 @@ pub const Block = struct { |
| 398 | /// The name of the current "context" for naming namespace types. | 398 | /// The name of the current "context" for naming namespace types. |
| 399 | /// The interpretation of this depends on the name strategy in ZIR, but the name | 399 | /// The interpretation of this depends on the name strategy in ZIR, but the name |
| 400 | /// is always incorporated into the type name somehow. | 400 | /// is always incorporated into the type name somehow. |
| 401 | /// See `Sema.setTypeName`. | 401 | /// See `Sema.computeTypeName`. |
| 402 | type_name_ctx: InternPool.NullTerminatedString, | 402 | type_name_ctx: InternPool.NullTerminatedString, |
| 403 | 403 | ||
| 404 | /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block. | 404 | /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block. |
| ... | @@ -1435,6 +1435,7 @@ fn analyzeBodyInner( | ... | @@ -1435,6 +1435,7 @@ fn analyzeBodyInner( |
| 1435 | .reify_pointer_sentinel_ty => try sema.zirReifyPointerSentinelTy(block, extended), | 1435 | .reify_pointer_sentinel_ty => try sema.zirReifyPointerSentinelTy(block, extended), |
| 1436 | .reify_tuple => try sema.zirReifyTuple( block, extended), | 1436 | .reify_tuple => try sema.zirReifyTuple( block, extended), |
| 1437 | .reify_pointer => try sema.zirReifyPointer( block, extended), | 1437 | .reify_pointer => try sema.zirReifyPointer( block, extended), |
| 1438 | .reify_restricted => try sema.zirReifyRestricted( block, extended, inst), | ||
| 1438 | .reify_fn => try sema.zirReifyFn( block, extended), | 1439 | .reify_fn => try sema.zirReifyFn( block, extended), |
| 1439 | .reify_struct => try sema.zirReifyStruct( block, extended, inst), | 1440 | .reify_struct => try sema.zirReifyStruct( block, extended, inst), |
| 1440 | .reify_union => try sema.zirReifyUnion( block, extended, inst), | 1441 | .reify_union => try sema.zirReifyUnion( block, extended, inst), |
| ... | @@ -18956,7 +18957,8 @@ fn structInitAnon( | ... | @@ -18956,7 +18957,8 @@ fn structInitAnon( |
| 18956 | .existing => |ty| .fromInterned(ty), | 18957 | .existing => |ty| .fromInterned(ty), |
| 18957 | .wip => |wip| ty: { | 18958 | .wip => |wip| ty: { |
| 18958 | errdefer wip.cancel(ip, pt.tid); | 18959 | errdefer wip.cancel(ip, pt.tid); |
| 18959 | try sema.setTypeName(block, &wip, .anon, "struct", inst); | 18960 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, .anon, "struct", inst); |
| 18961 | wip.setName(ip, type_name, name_nav); | ||
| 18960 | 18962 | ||
| 18961 | // Reified structs have field information populated immediately. | 18963 | // Reified structs have field information populated immediately. |
| 18962 | @memcpy(wip.field_names.get(ip), names); | 18964 | @memcpy(wip.field_names.get(ip), names); |
| ... | @@ -19879,6 +19881,62 @@ fn zirReifyPointer( | ... | @@ -19879,6 +19881,62 @@ fn zirReifyPointer( |
| 19879 | })); | 19881 | })); |
| 19880 | } | 19882 | } |
| 19881 | 19883 | ||
| 19884 | fn zirReifyRestricted( | ||
| 19885 | sema: *Sema, | ||
| 19886 | block: *Block, | ||
| 19887 | extended: Zir.Inst.Extended.InstData, | ||
| 19888 | inst: Zir.Inst.Index, | ||
| 19889 | ) CompileError!Air.Inst.Ref { | ||
| 19890 | const pt = sema.pt; | ||
| 19891 | const zcu = pt.zcu; | ||
| 19892 | const comp = zcu.comp; | ||
| 19893 | const gpa = comp.gpa; | ||
| 19894 | const io = comp.io; | ||
| 19895 | const ip = &zcu.intern_pool; | ||
| 19896 | |||
| 19897 | const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small); | ||
| 19898 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | ||
| 19899 | const tracked_inst = try block.trackZir(inst); | ||
| 19900 | |||
| 19901 | const src: LazySrcLoc = .{ | ||
| 19902 | .base_node_inst = tracked_inst, | ||
| 19903 | .offset = .nodeOffset(.zero), | ||
| 19904 | }; | ||
| 19905 | const ptr_type_src: LazySrcLoc = .{ | ||
| 19906 | .base_node_inst = tracked_inst, | ||
| 19907 | .offset = .{ .node_offset_builtin_call_arg = .{ | ||
| 19908 | .builtin_call_node = extra.node, | ||
| 19909 | .arg_index = 0, | ||
| 19910 | } }, | ||
| 19911 | }; | ||
| 19912 | |||
| 19913 | const operand = try sema.resolveType(block, src, extra.operand); | ||
| 19914 | const unrestricted_ptr_type: Type = switch (ip.indexToKey(operand.toIntern())) { | ||
| 19915 | else => return sema.fail(block, ptr_type_src, "expected pointer type, found '{f}'", .{operand.fmt(pt)}), | ||
| 19916 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | ||
| 19917 | .one, .many, .c => operand, | ||
| 19918 | .slice => return sema.fail(block, ptr_type_src, "slice types cannot be restricted", .{}), | ||
| 19919 | }, | ||
| 19920 | .restricted_ptr_type => |restricted_ptr_type| .fromInterned(restricted_ptr_type.unrestricted_ptr_type), | ||
| 19921 | }; | ||
| 19922 | |||
| 19923 | switch (try ip.getReifiedRestrictedType(gpa, io, pt.tid, tracked_inst, unrestricted_ptr_type.toIntern())) { | ||
| 19924 | .existing => |ty| { | ||
| 19925 | try sema.addTypeReferenceEntry(src, .fromInterned(ty)); | ||
| 19926 | // No need for `ensureNamespaceUpToDate` because this type doesn't have a namespace. | ||
| 19927 | return .fromIntern(ty); | ||
| 19928 | }, | ||
| 19929 | .wip => |wip| { | ||
| 19930 | errdefer wip.cancel(ip, pt.tid); | ||
| 19931 | const type_name, _ = try sema.computeTypeName(block, wip.index, name_strategy, "restricted", inst); | ||
| 19932 | wip.setName(ip, type_name); | ||
| 19933 | if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index); | ||
| 19934 | try sema.addTypeReferenceEntry(src, .fromInterned(wip.index)); | ||
| 19935 | return .fromIntern(wip.index); | ||
| 19936 | }, | ||
| 19937 | } | ||
| 19938 | } | ||
| 19939 | |||
| 19882 | fn zirReifyFn( | 19940 | fn zirReifyFn( |
| 19883 | sema: *Sema, | 19941 | sema: *Sema, |
| 19884 | block: *Block, | 19942 | block: *Block, |
| ... | @@ -20194,7 +20252,8 @@ fn zirReifyStruct( | ... | @@ -20194,7 +20252,8 @@ fn zirReifyStruct( |
| 20194 | }, | 20252 | }, |
| 20195 | .wip => |wip| { | 20253 | .wip => |wip| { |
| 20196 | errdefer wip.cancel(ip, pt.tid); | 20254 | errdefer wip.cancel(ip, pt.tid); |
| 20197 | try sema.setTypeName(block, &wip, name_strategy, "struct", inst); | 20255 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, name_strategy, "struct", inst); |
| 20256 | wip.setName(ip, type_name, name_nav); | ||
| 20198 | for (0..fields_len) |field_idx| { | 20257 | for (0..fields_len) |field_idx| { |
| 20199 | const field_name_val = try field_names_arr.elemValue(pt, field_idx); | 20258 | const field_name_val = try field_names_arr.elemValue(pt, field_idx); |
| 20200 | const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx); | 20259 | const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx); |
| ... | @@ -20438,7 +20497,8 @@ fn zirReifyUnion( | ... | @@ -20438,7 +20497,8 @@ fn zirReifyUnion( |
| 20438 | }, | 20497 | }, |
| 20439 | .wip => |wip| { | 20498 | .wip => |wip| { |
| 20440 | errdefer wip.cancel(ip, pt.tid); | 20499 | errdefer wip.cancel(ip, pt.tid); |
| 20441 | try sema.setTypeName(block, &wip, name_strategy, "union", inst); | 20500 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, name_strategy, "union", inst); |
| 20501 | wip.setName(ip, type_name, name_nav); | ||
| 20442 | 20502 | ||
| 20443 | for (0..fields_len) |field_idx| { | 20503 | for (0..fields_len) |field_idx| { |
| 20444 | const field_name_val = try field_names_arr.elemValue(pt, field_idx); | 20504 | const field_name_val = try field_names_arr.elemValue(pt, field_idx); |
| ... | @@ -20603,8 +20663,8 @@ fn zirReifyEnum( | ... | @@ -20603,8 +20663,8 @@ fn zirReifyEnum( |
| 20603 | }, | 20663 | }, |
| 20604 | .wip => |wip| { | 20664 | .wip => |wip| { |
| 20605 | errdefer wip.cancel(ip, pt.tid); | 20665 | errdefer wip.cancel(ip, pt.tid); |
| 20606 | 20666 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, name_strategy, "enum", inst); | |
| 20607 | try sema.setTypeName(block, &wip, name_strategy, "enum", inst); | 20667 | wip.setName(ip, type_name, name_nav); |
| 20608 | 20668 | ||
| 20609 | // Populate field names and values. Duplicate checking will be handled by type resolution. | 20669 | // Populate field names and values. Duplicate checking will be handled by type resolution. |
| 20610 | for (0..fields_len) |field_index| { | 20670 | for (0..fields_len) |field_index| { |
| ... | @@ -27736,6 +27796,22 @@ fn coerceExtra( | ... | @@ -27736,6 +27796,22 @@ fn coerceExtra( |
| 27736 | return sema.coerceCompatiblePtrs(block, dest_ty, slice_ptr, inst_src); | 27796 | return sema.coerceCompatiblePtrs(block, dest_ty, slice_ptr, inst_src); |
| 27737 | }, | 27797 | }, |
| 27738 | } | 27798 | } |
| 27799 | |||
| 27800 | // Restricted coercions | ||
| 27801 | if (maybe_inst_val != null) { | ||
| 27802 | if (dest_ty.unrestrictedType(zcu)) |dest_unrestricted_ty| { | ||
| 27803 | if (sema.resolveValue(try sema.coerceExtra(block, dest_unrestricted_ty, inst, inst_src, opts))) |inst_val| { | ||
| 27804 | return .fromIntern(try ip.getCoerced(gpa, io, pt.tid, inst_val.toIntern(), dest_ty.toIntern())); | ||
| 27805 | } | ||
| 27806 | } | ||
| 27807 | } | ||
| 27808 | if (inst_ty.unrestrictedType(zcu)) |inst_unrestricted_ty| { | ||
| 27809 | const inst_unrestricted: Air.Inst.Ref = if (maybe_inst_val) |inst_val| | ||
| 27810 | .fromIntern(try ip.getCoerced(gpa, io, pt.tid, inst_val.toIntern(), inst_unrestricted_ty.toIntern())) | ||
| 27811 | else | ||
| 27812 | try sema.unwrapRestrictedPtr(block, inst_unrestricted_ty, inst, inst_src); | ||
| 27813 | return sema.coerceExtra(block, dest_ty, inst_unrestricted, inst_src, opts); | ||
| 27814 | } | ||
| 27739 | }, | 27815 | }, |
| 27740 | .int, .comptime_int => switch (inst_ty.zigTypeTag(zcu)) { | 27816 | .int, .comptime_int => switch (inst_ty.zigTypeTag(zcu)) { |
| 27741 | .float, .comptime_float => float: { | 27817 | .float, .comptime_float => float: { |
| ... | @@ -28084,6 +28160,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -28084,6 +28160,7 @@ const InMemoryCoercionResult = union(enum) { |
| 28084 | ptr_alignment: AlignPair, | 28160 | ptr_alignment: AlignPair, |
| 28085 | double_ptr_to_anyopaque: Pair, | 28161 | double_ptr_to_anyopaque: Pair, |
| 28086 | slice_to_anyopaque: Pair, | 28162 | slice_to_anyopaque: Pair, |
| 28163 | ptr_restricted: Pair, | ||
| 28087 | 28164 | ||
| 28088 | const Pair = struct { | 28165 | const Pair = struct { |
| 28089 | actual: Type, | 28166 | actual: Type, |
| ... | @@ -28415,6 +28492,15 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -28415,6 +28492,15 @@ const InMemoryCoercionResult = union(enum) { |
| 28415 | try sema.errNote(src, msg, "consider using '.ptr'", .{}); | 28492 | try sema.errNote(src, msg, "consider using '.ptr'", .{}); |
| 28416 | break; | 28493 | break; |
| 28417 | }, | 28494 | }, |
| 28495 | .ptr_restricted => |pair| { | ||
| 28496 | for ([_]Type{ pair.actual, pair.wanted }) |restricted_ptr_type| { | ||
| 28497 | const unrestricted_ptr_type = restricted_ptr_type.unrestrictedType(pt.zcu) orelse continue; | ||
| 28498 | try sema.errNote(src, msg, "restricted type '{f}' is not guaranteed to have the same representation as its unrestricted type '{f}'", .{ | ||
| 28499 | restricted_ptr_type.fmt(pt), unrestricted_ptr_type.fmt(pt), | ||
| 28500 | }); | ||
| 28501 | } | ||
| 28502 | break; | ||
| 28503 | }, | ||
| 28418 | }; | 28504 | }; |
| 28419 | } | 28505 | } |
| 28420 | }; | 28506 | }; |
| ... | @@ -28479,7 +28565,7 @@ pub fn coerceInMemoryAllowed( | ... | @@ -28479,7 +28565,7 @@ pub fn coerceInMemoryAllowed( |
| 28479 | (dest_info.signedness == .signed and src_info.signedness == .unsigned and dest_info.bits <= src_info.bits) or | 28565 | (dest_info.signedness == .signed and src_info.signedness == .unsigned and dest_info.bits <= src_info.bits) or |
| 28480 | (dest_info.signedness == .unsigned and src_info.signedness == .signed)) | 28566 | (dest_info.signedness == .unsigned and src_info.signedness == .signed)) |
| 28481 | { | 28567 | { |
| 28482 | return InMemoryCoercionResult{ .int_not_coercible = .{ | 28568 | return .{ .int_not_coercible = .{ |
| 28483 | .actual_signedness = src_info.signedness, | 28569 | .actual_signedness = src_info.signedness, |
| 28484 | .wanted_signedness = dest_info.signedness, | 28570 | .wanted_signedness = dest_info.signedness, |
| 28485 | .actual_bits = src_info.bits, | 28571 | .actual_bits = src_info.bits, |
| ... | @@ -28913,7 +28999,7 @@ fn coerceInMemoryAllowedPtrs( | ... | @@ -28913,7 +28999,7 @@ fn coerceInMemoryAllowedPtrs( |
| 28913 | const ok_ptr_size = src_info.flags.size == dest_info.flags.size or | 28999 | const ok_ptr_size = src_info.flags.size == dest_info.flags.size or |
| 28914 | src_info.flags.size == .c or dest_info.flags.size == .c; | 29000 | src_info.flags.size == .c or dest_info.flags.size == .c; |
| 28915 | if (!ok_ptr_size) { | 29001 | if (!ok_ptr_size) { |
| 28916 | return InMemoryCoercionResult{ .ptr_size = .{ | 29002 | return .{ .ptr_size = .{ |
| 28917 | .actual = src_info.flags.size, | 29003 | .actual = src_info.flags.size, |
| 28918 | .wanted = dest_info.flags.size, | 29004 | .wanted = dest_info.flags.size, |
| 28919 | } }; | 29005 | } }; |
| ... | @@ -29049,13 +29135,19 @@ fn coerceInMemoryAllowedPtrs( | ... | @@ -29049,13 +29135,19 @@ fn coerceInMemoryAllowedPtrs( |
| 29049 | break :a dest_child.abiAlignment(zcu); | 29135 | break :a dest_child.abiAlignment(zcu); |
| 29050 | } else dest_info.flags.alignment; | 29136 | } else dest_info.flags.alignment; |
| 29051 | if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) { | 29137 | if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) { |
| 29052 | return InMemoryCoercionResult{ .ptr_alignment = .{ | 29138 | return .{ .ptr_alignment = .{ |
| 29053 | .actual = src_align, | 29139 | .actual = src_align, |
| 29054 | .wanted = dest_align, | 29140 | .wanted = dest_align, |
| 29055 | } }; | 29141 | } }; |
| 29056 | } | 29142 | } |
| 29057 | } | 29143 | } |
| 29058 | 29144 | ||
| 29145 | // Restricted pointers have a different in-memory representation depending on the safety mode of the module that created it. | ||
| 29146 | if (dest_ty.unrestrictedType(zcu) != null or src_ty.unrestrictedType(zcu) != null) return .{ .ptr_restricted = .{ | ||
| 29147 | .actual = src_ty, | ||
| 29148 | .wanted = dest_ty, | ||
| 29149 | } }; | ||
| 29150 | |||
| 29059 | return .ok; | 29151 | return .ok; |
| 29060 | } | 29152 | } |
| 29061 | 29153 | ||
| ... | @@ -29202,10 +29294,15 @@ fn storePtr2( | ... | @@ -29202,10 +29294,15 @@ fn storePtr2( |
| 29202 | 29294 | ||
| 29203 | try sema.requireRuntimeBlock(block, src, runtime_src); | 29295 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 29204 | 29296 | ||
| 29297 | const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty| | ||
| 29298 | try sema.unwrapRestrictedPtr(block, unrestricted_ptr_ty, ptr, ptr_src) | ||
| 29299 | else | ||
| 29300 | ptr; | ||
| 29301 | |||
| 29205 | const store_inst = if (is_ret) | 29302 | const store_inst = if (is_ret) |
| 29206 | try block.addBinOp(.store, ptr, operand) | 29303 | try block.addBinOp(.store, unrestricted_ptr, operand) |
| 29207 | else | 29304 | else |
| 29208 | try block.addBinOp(air_tag, ptr, operand); | 29305 | try block.addBinOp(air_tag, unrestricted_ptr, operand); |
| 29209 | 29306 | ||
| 29210 | try sema.checkComptimeKnownStore(block, store_inst, operand_src); | 29307 | try sema.checkComptimeKnownStore(block, store_inst, operand_src); |
| 29211 | 29308 | ||
| ... | @@ -30282,7 +30379,12 @@ fn analyzeLoad( | ... | @@ -30282,7 +30379,12 @@ fn analyzeLoad( |
| 30282 | break :msg msg; | 30379 | break :msg msg; |
| 30283 | }); | 30380 | }); |
| 30284 | 30381 | ||
| 30285 | return block.addTyOp(.load, elem_ty, ptr); | 30382 | const unrestricted_ptr = if (ptr_ty.unrestrictedType(zcu)) |unrestricted_ptr_ty| |
| 30383 | try sema.unwrapRestrictedPtr(block, unrestricted_ptr_ty, ptr, ptr_src) | ||
| 30384 | else | ||
| 30385 | ptr; | ||
| 30386 | |||
| 30387 | return block.addTyOp(.load, elem_ty, unrestricted_ptr); | ||
| 30286 | } | 30388 | } |
| 30287 | 30389 | ||
| 30288 | fn analyzeSlicePtr( | 30390 | fn analyzeSlicePtr( |
| ... | @@ -31494,6 +31596,19 @@ fn wrapErrorUnionSet( | ... | @@ -31494,6 +31596,19 @@ fn wrapErrorUnionSet( |
| 31494 | } | 31596 | } |
| 31495 | } | 31597 | } |
| 31496 | 31598 | ||
| 31599 | fn unwrapRestrictedPtr( | ||
| 31600 | sema: *Sema, | ||
| 31601 | block: *Block, | ||
| 31602 | unrestricted_ptr_ty: Type, | ||
| 31603 | ptr: Air.Inst.Ref, | ||
| 31604 | ptr_src: LazySrcLoc, | ||
| 31605 | ) !Air.Inst.Ref { | ||
| 31606 | return block.addTyOp(if (block.wantSafety()) tag: { | ||
| 31607 | try sema.preparePanicId(ptr_src, .corrupt_restricted_pointer); | ||
| 31608 | break :tag .unwrap_restricted_safe; | ||
| 31609 | } else .unwrap_restricted, unrestricted_ptr_ty, ptr); | ||
| 31610 | } | ||
| 31611 | |||
| 31497 | /// Returns the enum tag value for the active tag of a tagged union value. | 31612 | /// Returns the enum tag value for the active tag of a tagged union value. |
| 31498 | /// | 31613 | /// |
| 31499 | /// Asserts that the type of `un` is a tagged union type. | 31614 | /// Asserts that the type of `un` is a tagged union type. |
| ... | @@ -34211,13 +34326,59 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C | ... | @@ -34211,13 +34326,59 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C |
| 34211 | fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Type { | 34326 | fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Type { |
| 34212 | const pt = sema.pt; | 34327 | const pt = sema.pt; |
| 34213 | return switch (decl) { | 34328 | return switch (decl) { |
| 34329 | .Signedness, | ||
| 34330 | .AddressSpace, | ||
| 34331 | .CallingConvention, | ||
| 34332 | => unreachable, | ||
| 34214 | // `noinline fn () void` | 34333 | // `noinline fn () void` |
| 34215 | .returnError => try pt.funcType(.{ | 34334 | .returnError => try pt.funcType(.{ |
| 34216 | .param_types = &.{}, | 34335 | .param_types = &.{}, |
| 34217 | .return_type = .void_type, | 34336 | .return_type = .void_type, |
| 34218 | .is_noinline = true, | 34337 | .is_noinline = true, |
| 34219 | }), | 34338 | }), |
| 34339 | .StackTrace, | ||
| 34340 | .SourceLocation, | ||
| 34341 | .CallModifier, | ||
| 34342 | .AtomicOrder, | ||
| 34343 | .AtomicRmwOp, | ||
| 34344 | .ReduceOp, | ||
| 34345 | .FloatMode, | ||
| 34346 | .PrefetchOptions, | ||
| 34347 | .ExportOptions, | ||
| 34348 | .ExternOptions, | ||
| 34349 | .BranchHint, | ||
| 34350 | => unreachable, | ||
| 34351 | |||
| 34352 | .Type, | ||
| 34353 | .@"Type.Fn", | ||
| 34354 | .@"Type.Fn.Param", | ||
| 34355 | .@"Type.Fn.Param.Attributes", | ||
| 34356 | .@"Type.Fn.Attributes", | ||
| 34357 | .@"Type.Int", | ||
| 34358 | .@"Type.Float", | ||
| 34359 | .@"Type.Pointer", | ||
| 34360 | .@"Type.Pointer.Size", | ||
| 34361 | .@"Type.Pointer.Attributes", | ||
| 34362 | .@"Type.Array", | ||
| 34363 | .@"Type.Vector", | ||
| 34364 | .@"Type.Optional", | ||
| 34365 | .@"Type.Error", | ||
| 34366 | .@"Type.ErrorUnion", | ||
| 34367 | .@"Type.EnumField", | ||
| 34368 | .@"Type.Enum", | ||
| 34369 | .@"Type.Enum.Mode", | ||
| 34370 | .@"Type.Union", | ||
| 34371 | .@"Type.UnionField", | ||
| 34372 | .@"Type.UnionField.Attributes", | ||
| 34373 | .@"Type.Struct", | ||
| 34374 | .@"Type.StructField", | ||
| 34375 | .@"Type.StructField.Attributes", | ||
| 34376 | .@"Type.ContainerLayout", | ||
| 34377 | .@"Type.Opaque", | ||
| 34378 | .@"Type.Declaration", | ||
| 34379 | => unreachable, | ||
| 34220 | 34380 | ||
| 34381 | .panic => unreachable, | ||
| 34221 | // `fn ([]const u8, ?usize) noreturn` | 34382 | // `fn ([]const u8, ?usize) noreturn` |
| 34222 | .@"panic.call" => try pt.funcType(.{ | 34383 | .@"panic.call" => try pt.funcType(.{ |
| 34223 | .param_types = &.{ | 34384 | .param_types = &.{ |
| ... | @@ -34226,7 +34387,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ | ... | @@ -34226,7 +34387,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34226 | }, | 34387 | }, |
| 34227 | .return_type = .noreturn_type, | 34388 | .return_type = .noreturn_type, |
| 34228 | }), | 34389 | }), |
| 34229 | |||
| 34230 | // `fn (anytype, anytype) noreturn` | 34390 | // `fn (anytype, anytype) noreturn` |
| 34231 | .@"panic.sentinelMismatch", | 34391 | .@"panic.sentinelMismatch", |
| 34232 | .@"panic.inactiveUnionField", | 34392 | .@"panic.inactiveUnionField", |
| ... | @@ -34234,19 +34394,16 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ | ... | @@ -34234,19 +34394,16 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34234 | .param_types = &.{ .generic_poison_type, .generic_poison_type }, | 34394 | .param_types = &.{ .generic_poison_type, .generic_poison_type }, |
| 34235 | .return_type = .noreturn_type, | 34395 | .return_type = .noreturn_type, |
| 34236 | }), | 34396 | }), |
| 34237 | |||
| 34238 | // `fn (anyerror) noreturn` | 34397 | // `fn (anyerror) noreturn` |
| 34239 | .@"panic.unwrapError" => try pt.funcType(.{ | 34398 | .@"panic.unwrapError" => try pt.funcType(.{ |
| 34240 | .param_types = &.{.anyerror_type}, | 34399 | .param_types = &.{.anyerror_type}, |
| 34241 | .return_type = .noreturn_type, | 34400 | .return_type = .noreturn_type, |
| 34242 | }), | 34401 | }), |
| 34243 | |||
| 34244 | // `fn (usize) noreturn` | 34402 | // `fn (usize) noreturn` |
| 34245 | .@"panic.sliceCastLenRemainder" => try pt.funcType(.{ | 34403 | .@"panic.sliceCastLenRemainder" => try pt.funcType(.{ |
| 34246 | .param_types = &.{.usize_type}, | 34404 | .param_types = &.{.usize_type}, |
| 34247 | .return_type = .noreturn_type, | 34405 | .return_type = .noreturn_type, |
| 34248 | }), | 34406 | }), |
| 34249 | |||
| 34250 | // `fn (usize, usize) noreturn` | 34407 | // `fn (usize, usize) noreturn` |
| 34251 | .@"panic.outOfBounds", | 34408 | .@"panic.outOfBounds", |
| 34252 | .@"panic.startGreaterThanEnd", | 34409 | .@"panic.startGreaterThanEnd", |
| ... | @@ -34254,7 +34411,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ | ... | @@ -34254,7 +34411,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34254 | .param_types = &.{ .usize_type, .usize_type }, | 34411 | .param_types = &.{ .usize_type, .usize_type }, |
| 34255 | .return_type = .noreturn_type, | 34412 | .return_type = .noreturn_type, |
| 34256 | }), | 34413 | }), |
| 34257 | |||
| 34258 | // `fn () noreturn` | 34414 | // `fn () noreturn` |
| 34259 | .@"panic.reachedUnreachable", | 34415 | .@"panic.reachedUnreachable", |
| 34260 | .@"panic.unwrapNull", | 34416 | .@"panic.unwrapNull", |
| ... | @@ -34275,23 +34431,28 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ | ... | @@ -34275,23 +34431,28 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ |
| 34275 | .@"panic.copyLenMismatch", | 34431 | .@"panic.copyLenMismatch", |
| 34276 | .@"panic.memcpyAlias", | 34432 | .@"panic.memcpyAlias", |
| 34277 | .@"panic.noreturnReturned", | 34433 | .@"panic.noreturnReturned", |
| 34434 | .@"panic.corruptRestrictedPointer", | ||
| 34278 | => try pt.funcType(.{ | 34435 | => try pt.funcType(.{ |
| 34279 | .param_types = &.{}, | 34436 | .param_types = &.{}, |
| 34280 | .return_type = .noreturn_type, | 34437 | .return_type = .noreturn_type, |
| 34281 | }), | 34438 | }), |
| 34282 | 34439 | ||
| 34283 | else => unreachable, | 34440 | .VaList => unreachable, |
| 34441 | |||
| 34442 | .assembly, | ||
| 34443 | .@"assembly.Clobbers", | ||
| 34444 | => unreachable, | ||
| 34284 | }; | 34445 | }; |
| 34285 | } | 34446 | } |
| 34286 | 34447 | ||
| 34287 | pub fn setTypeName( | 34448 | pub fn computeTypeName( |
| 34288 | sema: *Sema, | 34449 | sema: *Sema, |
| 34289 | block: *Block, | 34450 | block: *Block, |
| 34290 | wip: *const InternPool.WipContainerType, | 34451 | index: InternPool.Index, |
| 34291 | name_strategy: Zir.Inst.NameStrategy, | 34452 | name_strategy: Zir.Inst.NameStrategy, |
| 34292 | anon_prefix: []const u8, | 34453 | anon_prefix: []const u8, |
| 34293 | inst: Zir.Inst.Index, | 34454 | inst: Zir.Inst.Index, |
| 34294 | ) CompileError!void { | 34455 | ) CompileError!struct { InternPool.NullTerminatedString, InternPool.Nav.Index.Optional } { |
| 34295 | const pt = sema.pt; | 34456 | const pt = sema.pt; |
| 34296 | const zcu = pt.zcu; | 34457 | const zcu = pt.zcu; |
| 34297 | const comp = zcu.comp; | 34458 | const comp = zcu.comp; |
| ... | @@ -34308,16 +34469,16 @@ pub fn setTypeName( | ... | @@ -34308,16 +34469,16 @@ pub fn setTypeName( |
| 34308 | // TODO: that would be possible, by detecting line number changes and renaming | 34469 | // TODO: that would be possible, by detecting line number changes and renaming |
| 34309 | // types appropriately. However, `@typeName` becomes a problem then. If we remove | 34470 | // types appropriately. However, `@typeName` becomes a problem then. If we remove |
| 34310 | // that builtin from the language, we can consider this. | 34471 | // that builtin from the language, we can consider this. |
| 34311 | wip.setName(ip, try ip.getOrPutStringFmt( | 34472 | return .{ try ip.getOrPutStringFmt( |
| 34312 | gpa, | 34473 | gpa, |
| 34313 | io, | 34474 | io, |
| 34314 | pt.tid, | 34475 | pt.tid, |
| 34315 | "{f}__{s}_{d}", | 34476 | "{f}__{s}_{d}", |
| 34316 | .{ block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(wip.index) }, | 34477 | .{ block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(index) }, |
| 34317 | .no_embedded_nulls, | 34478 | .no_embedded_nulls, |
| 34318 | ), .none); | 34479 | ), .none }; |
| 34319 | }, | 34480 | }, |
| 34320 | .parent => wip.setName(ip, block.type_name_ctx, sema.owner.unwrap().nav_val.toOptional()), | 34481 | .parent => return .{ block.type_name_ctx, sema.owner.unwrap().nav_val.toOptional() }, |
| 34321 | .func => { | 34482 | .func => { |
| 34322 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail); | 34483 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail); |
| 34323 | const zir_tags = sema.code.instructions.items(.tag); | 34484 | const zir_tags = sema.code.instructions.items(.tag); |
| ... | @@ -34360,8 +34521,7 @@ pub fn setTypeName( | ... | @@ -34360,8 +34521,7 @@ pub fn setTypeName( |
| 34360 | }; | 34521 | }; |
| 34361 | 34522 | ||
| 34362 | w.writeByte(')') catch return error.OutOfMemory; | 34523 | w.writeByte(')') catch return error.OutOfMemory; |
| 34363 | const name = try ip.getOrPutString(gpa, io, pt.tid, aw.written(), .no_embedded_nulls); | 34524 | return .{ try ip.getOrPutString(gpa, io, pt.tid, aw.written(), .no_embedded_nulls), .none }; |
| 34364 | wip.setName(ip, name, .none); | ||
| 34365 | }, | 34525 | }, |
| 34366 | .dbg_var => { | 34526 | .dbg_var => { |
| 34367 | // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions. | 34527 | // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions. |
| ... | @@ -34376,10 +34536,9 @@ pub fn setTypeName( | ... | @@ -34376,10 +34536,9 @@ pub fn setTypeName( |
| 34376 | } else { | 34536 | } else { |
| 34377 | continue :strat .anon; | 34537 | continue :strat .anon; |
| 34378 | }; | 34538 | }; |
| 34379 | const name = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.{s}", .{ | 34539 | return .{ try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.{s}", .{ |
| 34380 | block.type_name_ctx.fmt(ip), var_name, | 34540 | block.type_name_ctx.fmt(ip), var_name, |
| 34381 | }, .no_embedded_nulls); | 34541 | }, .no_embedded_nulls), .none }; |
| 34382 | wip.setName(ip, name, .none); | ||
| 34383 | }, | 34542 | }, |
| 34384 | } | 34543 | } |
| 34385 | } | 34544 | } |
| ... | @@ -34420,7 +34579,8 @@ fn zirStructDecl( | ... | @@ -34420,7 +34579,8 @@ fn zirStructDecl( |
| 34420 | .existing => |ty| .fromInterned(ty), | 34579 | .existing => |ty| .fromInterned(ty), |
| 34421 | .wip => |wip| ty: { | 34580 | .wip => |wip| ty: { |
| 34422 | errdefer wip.cancel(ip, pt.tid); | 34581 | errdefer wip.cancel(ip, pt.tid); |
| 34423 | try sema.setTypeName(block, &wip, struct_decl.name_strategy, "struct", inst); | 34582 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, struct_decl.name_strategy, "struct", inst); |
| 34583 | wip.setName(ip, type_name, name_nav); | ||
| 34424 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ | 34584 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 34425 | .parent = block.namespace.toOptional(), | 34585 | .parent = block.namespace.toOptional(), |
| 34426 | .owner_type = wip.index, | 34586 | .owner_type = wip.index, |
| ... | @@ -34493,7 +34653,8 @@ fn zirUnionDecl( | ... | @@ -34493,7 +34653,8 @@ fn zirUnionDecl( |
| 34493 | .existing => |ty| .fromInterned(ty), | 34653 | .existing => |ty| .fromInterned(ty), |
| 34494 | .wip => |wip| ty: { | 34654 | .wip => |wip| ty: { |
| 34495 | errdefer wip.cancel(ip, pt.tid); | 34655 | errdefer wip.cancel(ip, pt.tid); |
| 34496 | try sema.setTypeName(block, &wip, union_decl.name_strategy, "union", inst); | 34656 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, union_decl.name_strategy, "union", inst); |
| 34657 | wip.setName(ip, type_name, name_nav); | ||
| 34497 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ | 34658 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 34498 | .parent = block.namespace.toOptional(), | 34659 | .parent = block.namespace.toOptional(), |
| 34499 | .owner_type = wip.index, | 34660 | .owner_type = wip.index, |
| ... | @@ -34545,7 +34706,8 @@ fn zirEnumDecl( | ... | @@ -34545,7 +34706,8 @@ fn zirEnumDecl( |
| 34545 | .existing => |ty| .fromInterned(ty), | 34706 | .existing => |ty| .fromInterned(ty), |
| 34546 | .wip => |wip| ty: { | 34707 | .wip => |wip| ty: { |
| 34547 | errdefer wip.cancel(ip, pt.tid); | 34708 | errdefer wip.cancel(ip, pt.tid); |
| 34548 | try sema.setTypeName(block, &wip, enum_decl.name_strategy, "enum", inst); | 34709 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, enum_decl.name_strategy, "enum", inst); |
| 34710 | wip.setName(ip, type_name, name_nav); | ||
| 34549 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ | 34711 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 34550 | .parent = block.namespace.toOptional(), | 34712 | .parent = block.namespace.toOptional(), |
| 34551 | .owner_type = wip.index, | 34713 | .owner_type = wip.index, |
| ... | @@ -34594,7 +34756,8 @@ fn zirOpaqueDecl( | ... | @@ -34594,7 +34756,8 @@ fn zirOpaqueDecl( |
| 34594 | .existing => |ty| .fromInterned(ty), | 34756 | .existing => |ty| .fromInterned(ty), |
| 34595 | .wip => |wip| ty: { | 34757 | .wip => |wip| ty: { |
| 34596 | errdefer wip.cancel(ip, pt.tid); | 34758 | errdefer wip.cancel(ip, pt.tid); |
| 34597 | try sema.setTypeName(block, &wip, opaque_decl.name_strategy, "opaque", inst); | 34759 | const type_name, const name_nav = try sema.computeTypeName(block, wip.index, opaque_decl.name_strategy, "opaque", inst); |
| 34760 | wip.setName(ip, type_name, name_nav); | ||
| 34598 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ | 34761 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 34599 | .parent = block.namespace.toOptional(), | 34762 | .parent = block.namespace.toOptional(), |
| 34600 | .owner_type = wip.index, | 34763 | .owner_type = wip.index, |
src/Sema/LowerZon.zig+2-1| ... | @@ -150,7 +150,8 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter | ... | @@ -150,7 +150,8 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter |
| 150 | errdefer wip.cancel(ip, pt.tid); | 150 | errdefer wip.cancel(ip, pt.tid); |
| 151 | const block = self.block; | 151 | const block = self.block; |
| 152 | const zcu = pt.zcu; | 152 | const zcu = pt.zcu; |
| 153 | try self.sema.setTypeName(block, &wip, .anon, "struct", self.base_node_inst.resolve(ip).?); | 153 | const type_name, const name_nav = try self.sema.computeTypeName(block, wip.index, .anon, "struct", self.base_node_inst.resolve(ip).?); |
| 154 | wip.setName(ip, type_name, name_nav); | ||
| 154 | 155 | ||
| 155 | // Reified structs have field information populated immediately. | 156 | // Reified structs have field information populated immediately. |
| 156 | @memcpy(wip.field_values.get(ip), elems); | 157 | @memcpy(wip.field_values.get(ip), elems); |
src/Sema/bitcast.zig+1| ... | @@ -239,6 +239,7 @@ const UnpackValueBits = struct { | ... | @@ -239,6 +239,7 @@ const UnpackValueBits = struct { |
| 239 | switch (ip.indexToKey(val.toIntern())) { | 239 | switch (ip.indexToKey(val.toIntern())) { |
| 240 | .int_type, | 240 | .int_type, |
| 241 | .ptr_type, | 241 | .ptr_type, |
| 242 | .restricted_ptr_type, | ||
| 242 | .array_type, | 243 | .array_type, |
| 243 | .vector_type, | 244 | .vector_type, |
| 244 | .opt_type, | 245 | .opt_type, |
src/Sema/type_resolution.zig+1| ... | @@ -84,6 +84,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons | ... | @@ -84,6 +84,7 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons |
| 84 | switch (ip.indexToKey(ty.toIntern())) { | 84 | switch (ip.indexToKey(ty.toIntern())) { |
| 85 | .int_type, | 85 | .int_type, |
| 86 | .ptr_type, | 86 | .ptr_type, |
| 87 | .restricted_ptr_type, | ||
| 87 | .anyframe_type, | 88 | .anyframe_type, |
| 88 | .simple_type, | 89 | .simple_type, |
| 89 | .opaque_type, | 90 | .opaque_type, |
src/Type.zig+138-70| ... | @@ -165,6 +165,7 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class { | ... | @@ -165,6 +165,7 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class { |
| 165 | .error_set_type, | 165 | .error_set_type, |
| 166 | .inferred_error_set_type, | 166 | .inferred_error_set_type, |
| 167 | .ptr_type, | 167 | .ptr_type, |
| 168 | .restricted_ptr_type, | ||
| 168 | .anyframe_type, | 169 | .anyframe_type, |
| 169 | => .runtime, | 170 | => .runtime, |
| 170 | 171 | ||
| ... | @@ -373,13 +374,28 @@ pub fn arrayInfo(self: Type, zcu: *const Zcu) ArrayInfo { | ... | @@ -373,13 +374,28 @@ pub fn arrayInfo(self: Type, zcu: *const Zcu) ArrayInfo { |
| 373 | } | 374 | } |
| 374 | 375 | ||
| 375 | pub fn ptrInfo(ty: Type, zcu: *const Zcu) InternPool.Key.PtrType { | 376 | pub fn ptrInfo(ty: Type, zcu: *const Zcu) InternPool.Key.PtrType { |
| 376 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 377 | return ty.ptrInfoOrNull(&zcu.intern_pool, .{}).?; |
| 378 | } | ||
| 379 | |||
| 380 | pub fn ptrInfoOrNull(ty: Type, ip: *const InternPool, comptime opts: struct { | ||
| 381 | allow_optional: bool = true, | ||
| 382 | allow_restricted: bool = true, | ||
| 383 | }) ?InternPool.Key.PtrType { | ||
| 384 | return switch (ip.indexToKey(ty.toIntern())) { | ||
| 377 | .ptr_type => |p| p, | 385 | .ptr_type => |p| p, |
| 378 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | 386 | .restricted_ptr_type => |rp| if (opts.allow_restricted) |
| 387 | ip.indexToKey(rp.unrestricted_ptr_type).ptr_type | ||
| 388 | else | ||
| 389 | null, | ||
| 390 | .opt_type => |child| if (opts.allow_optional) switch (ip.indexToKey(child)) { | ||
| 379 | .ptr_type => |p| p, | 391 | .ptr_type => |p| p, |
| 380 | else => unreachable, | 392 | .restricted_ptr_type => |rp| if (opts.allow_restricted) |
| 381 | }, | 393 | ip.indexToKey(rp.unrestricted_ptr_type).ptr_type |
| 382 | else => unreachable, | 394 | else |
| 395 | null, | ||
| 396 | else => null, // not a pointer type | ||
| 397 | } else null, | ||
| 398 | else => null, // not a pointer type | ||
| 383 | }; | 399 | }; |
| 384 | } | 400 | } |
| 385 | 401 | ||
| ... | @@ -488,6 +504,10 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari | ... | @@ -488,6 +504,10 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari |
| 488 | try print(Type.fromInterned(info.child), writer, pt, ctx); | 504 | try print(Type.fromInterned(info.child), writer, pt, ctx); |
| 489 | return; | 505 | return; |
| 490 | }, | 506 | }, |
| 507 | .restricted_ptr_type => { | ||
| 508 | const name = ip.loadRestrictedType(ty.toIntern()).name; | ||
| 509 | try writer.print("{f}", .{name.fmt(ip)}); | ||
| 510 | }, | ||
| 491 | .array_type => |array_type| { | 511 | .array_type => |array_type| { |
| 492 | if (array_type.sentinel == .none) { | 512 | if (array_type.sentinel == .none) { |
| 493 | try writer.print("[{d}]", .{array_type.len}); | 513 | try writer.print("[{d}]", .{array_type.len}); |
| ... | @@ -747,6 +767,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool { | ... | @@ -747,6 +767,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool { |
| 747 | .vector_type, | 767 | .vector_type, |
| 748 | => true, | 768 | => true, |
| 749 | 769 | ||
| 770 | .restricted_ptr_type, | ||
| 750 | .error_union_type, | 771 | .error_union_type, |
| 751 | .error_set_type, | 772 | .error_set_type, |
| 752 | .inferred_error_set_type, | 773 | .inferred_error_set_type, |
| ... | @@ -893,22 +914,13 @@ pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool { | ... | @@ -893,22 +914,13 @@ pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool { |
| 893 | 914 | ||
| 894 | /// Never returns `none`. Asserts that all necessary type resolution is already done. | 915 | /// Never returns `none`. Asserts that all necessary type resolution is already done. |
| 895 | pub fn ptrAlignment(ptr_ty: Type, zcu: *Zcu) Alignment { | 916 | pub fn ptrAlignment(ptr_ty: Type, zcu: *Zcu) Alignment { |
| 896 | const ip = &zcu.intern_pool; | 917 | const ptr_key = ptr_ty.ptrInfo(zcu); |
| 897 | const ptr_key: InternPool.Key.PtrType = switch (ip.indexToKey(ptr_ty.toIntern())) { | ||
| 898 | .ptr_type => |key| key, | ||
| 899 | .opt_type => |child| ip.indexToKey(child).ptr_type, | ||
| 900 | else => unreachable, | ||
| 901 | }; | ||
| 902 | if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment; | 918 | if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment; |
| 903 | return Type.fromInterned(ptr_key.child).abiAlignment(zcu); | 919 | return Type.fromInterned(ptr_key.child).abiAlignment(zcu); |
| 904 | } | 920 | } |
| 905 | 921 | ||
| 906 | pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace { | 922 | pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace { |
| 907 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 923 | return ty.ptrInfo(zcu).flags.address_space; |
| 908 | .ptr_type => |ptr_type| ptr_type.flags.address_space, | ||
| 909 | .opt_type => |child| zcu.intern_pool.indexToKey(child).ptr_type.flags.address_space, | ||
| 910 | else => unreachable, | ||
| 911 | }; | ||
| 912 | } | 924 | } |
| 913 | 925 | ||
| 914 | /// Never returns `.none`. Asserts that the layout of `ty` is resolved. | 926 | /// Never returns `.none`. Asserts that the layout of `ty` is resolved. |
| ... | @@ -924,7 +936,7 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { | ... | @@ -924,7 +936,7 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { |
| 924 | if (int_type.bits == 0) return .@"1"; | 936 | if (int_type.bits == 0) return .@"1"; |
| 925 | return .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits)); | 937 | return .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits)); |
| 926 | }, | 938 | }, |
| 927 | .ptr_type, .anyframe_type => ptrAbiAlignment(target), | 939 | .ptr_type, .restricted_ptr_type, .anyframe_type => ptrAbiAlignment(target), |
| 928 | .array_type => |array_type| Type.fromInterned(array_type.child).abiAlignment(zcu), | 940 | .array_type => |array_type| Type.fromInterned(array_type.child).abiAlignment(zcu), |
| 929 | .vector_type => |vector_type| { | 941 | .vector_type => |vector_type| { |
| 930 | if (vector_type.len == 0) return .@"1"; | 942 | if (vector_type.len == 0) return .@"1"; |
| ... | @@ -1078,7 +1090,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { | ... | @@ -1078,7 +1090,7 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { |
| 1078 | .slice => ptrAbiSize(target) * 2, | 1090 | .slice => ptrAbiSize(target) * 2, |
| 1079 | .one, .many, .c => ptrAbiSize(target), | 1091 | .one, .many, .c => ptrAbiSize(target), |
| 1080 | }, | 1092 | }, |
| 1081 | .anyframe_type => ptrAbiSize(target), | 1093 | .restricted_ptr_type, .anyframe_type => ptrAbiSize(target), |
| 1082 | .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu), | 1094 | .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu), |
| 1083 | .vector_type => |vec| { | 1095 | .vector_type => |vec| { |
| 1084 | const elem_ty: Type = .fromInterned(vec.child); | 1096 | const elem_ty: Type = .fromInterned(vec.child); |
| ... | @@ -1231,7 +1243,7 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { | ... | @@ -1231,7 +1243,7 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { |
| 1231 | .slice => target.ptrBitWidth() * 2, | 1243 | .slice => target.ptrBitWidth() * 2, |
| 1232 | else => target.ptrBitWidth(), | 1244 | else => target.ptrBitWidth(), |
| 1233 | }, | 1245 | }, |
| 1234 | .anyframe_type => target.ptrBitWidth(), | 1246 | .restricted_ptr_type, .anyframe_type => target.ptrBitWidth(), |
| 1235 | .array_type => |array_type| { | 1247 | .array_type => |array_type| { |
| 1236 | const elem_ty: Type = .fromInterned(array_type.child); | 1248 | const elem_ty: Type = .fromInterned(array_type.child); |
| 1237 | const len = array_type.lenIncludingSentinel(); | 1249 | const len = array_type.lenIncludingSentinel(); |
| ... | @@ -1329,13 +1341,31 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { | ... | @@ -1329,13 +1341,31 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { |
| 1329 | }; | 1341 | }; |
| 1330 | } | 1342 | } |
| 1331 | 1343 | ||
| 1332 | pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool { | 1344 | /// Returns `null` if `ty` is not a restricted pointer. |
| 1333 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1345 | pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type { |
| 1334 | .ptr_type => |ptr_info| ptr_info.flags.size == .one, | 1346 | const ip = &zcu.intern_pool; |
| 1335 | else => false, | 1347 | return switch (ip.indexToKey(ty.toIntern())) { |
| 1348 | .restricted_ptr_type => |restricted_ptr_type| return .fromInterned(restricted_ptr_type.unrestricted_ptr_type), | ||
| 1349 | else => null, | ||
| 1350 | }; | ||
| 1351 | } | ||
| 1352 | |||
| 1353 | const RestrictedRepr = enum { double_pointer, single_pointer }; | ||
| 1354 | pub fn restrictedRepr(ty: Type, zcu: *const Zcu) RestrictedRepr { | ||
| 1355 | return restrictedReprByZirIndex(zcu.intern_pool.indexToKey(ty.toIntern()).restricted_ptr_type.zir_index, zcu); | ||
| 1356 | } | ||
| 1357 | pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr { | ||
| 1358 | return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) { | ||
| 1359 | .Debug, .ReleaseSafe => .double_pointer, | ||
| 1360 | .ReleaseFast, .ReleaseSmall => .single_pointer, | ||
| 1336 | }; | 1361 | }; |
| 1337 | } | 1362 | } |
| 1338 | 1363 | ||
| 1364 | pub fn isSinglePointer(ty: Type, zcu: *const Zcu) bool { | ||
| 1365 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; | ||
| 1366 | return ptr_info.flags.size == .one; | ||
| 1367 | } | ||
| 1368 | |||
| 1339 | /// Asserts `ty` is a pointer. | 1369 | /// Asserts `ty` is a pointer. |
| 1340 | pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size { | 1370 | pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size { |
| 1341 | return ty.ptrSizeOrNull(zcu).?; | 1371 | return ty.ptrSizeOrNull(zcu).?; |
| ... | @@ -1343,24 +1373,27 @@ pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size { | ... | @@ -1343,24 +1373,27 @@ pub fn ptrSize(ty: Type, zcu: *const Zcu) std.builtin.Type.Pointer.Size { |
| 1343 | 1373 | ||
| 1344 | /// Returns `null` if `ty` is not a pointer. | 1374 | /// Returns `null` if `ty` is not a pointer. |
| 1345 | pub fn ptrSizeOrNull(ty: Type, zcu: *const Zcu) ?std.builtin.Type.Pointer.Size { | 1375 | pub fn ptrSizeOrNull(ty: Type, zcu: *const Zcu) ?std.builtin.Type.Pointer.Size { |
| 1346 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1376 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return null; |
| 1347 | .ptr_type => |ptr_info| ptr_info.flags.size, | 1377 | return ptr_info.flags.size; |
| 1348 | else => null, | ||
| 1349 | }; | ||
| 1350 | } | 1378 | } |
| 1351 | 1379 | ||
| 1352 | pub fn isSlice(ty: Type, zcu: *const Zcu) bool { | 1380 | pub fn isSlice(ty: Type, zcu: *const Zcu) bool { |
| 1353 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1381 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; |
| 1354 | .ptr_type => |ptr_type| ptr_type.flags.size == .slice, | 1382 | return ptr_info.flags.size == .slice; |
| 1355 | else => false, | ||
| 1356 | }; | ||
| 1357 | } | 1383 | } |
| 1358 | 1384 | ||
| 1359 | pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool { | 1385 | pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool { |
| 1360 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1386 | const ip = &zcu.intern_pool; |
| 1387 | return ty: switch (ip.indexToKey(ty.toIntern())) { | ||
| 1361 | .ptr_type => |ptr_type| ptr_type.flags.size == .slice, | 1388 | .ptr_type => |ptr_type| ptr_type.flags.size == .slice, |
| 1362 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | 1389 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ |
| 1390 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1391 | }, | ||
| 1392 | .opt_type => |child| opt_child: switch (zcu.intern_pool.indexToKey(child)) { | ||
| 1363 | .ptr_type => |ptr_type| !ptr_type.flags.is_allowzero and ptr_type.flags.size == .slice, | 1393 | .ptr_type => |ptr_type| !ptr_type.flags.is_allowzero and ptr_type.flags.size == .slice, |
| 1394 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | ||
| 1395 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1396 | }, | ||
| 1364 | else => false, | 1397 | else => false, |
| 1365 | }, | 1398 | }, |
| 1366 | else => false, | 1399 | else => false, |
| ... | @@ -1372,10 +1405,8 @@ pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type { | ... | @@ -1372,10 +1405,8 @@ pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type { |
| 1372 | } | 1405 | } |
| 1373 | 1406 | ||
| 1374 | pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool { | 1407 | pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool { |
| 1375 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1408 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; |
| 1376 | .ptr_type => |ptr_type| ptr_type.flags.is_const, | 1409 | return ptr_info.flags.is_const; |
| 1377 | else => false, | ||
| 1378 | }; | ||
| 1379 | } | 1410 | } |
| 1380 | 1411 | ||
| 1381 | pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { | 1412 | pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { |
| ... | @@ -1383,38 +1414,45 @@ pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { | ... | @@ -1383,38 +1414,45 @@ pub fn isVolatilePtr(ty: Type, zcu: *const Zcu) bool { |
| 1383 | } | 1414 | } |
| 1384 | 1415 | ||
| 1385 | pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool { | 1416 | pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool { |
| 1386 | return switch (ip.indexToKey(ty.toIntern())) { | 1417 | const ptr_info = ty.ptrInfoOrNull(ip, .{ .allow_optional = false }) orelse return false; |
| 1387 | .ptr_type => |ptr_type| ptr_type.flags.is_volatile, | 1418 | return ptr_info.flags.is_volatile; |
| 1388 | else => false, | ||
| 1389 | }; | ||
| 1390 | } | 1419 | } |
| 1391 | 1420 | ||
| 1392 | pub fn isAllowzeroPtr(ty: Type, zcu: *const Zcu) bool { | 1421 | pub fn isAllowzeroPtr(ty: Type, zcu: *const Zcu) bool { |
| 1393 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1422 | const ip = &zcu.intern_pool; |
| 1423 | return ty: switch (ip.indexToKey(ty.toIntern())) { | ||
| 1394 | .ptr_type => |ptr_type| ptr_type.flags.is_allowzero, | 1424 | .ptr_type => |ptr_type| ptr_type.flags.is_allowzero, |
| 1425 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | ||
| 1426 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1427 | }, | ||
| 1395 | .opt_type => true, | 1428 | .opt_type => true, |
| 1396 | else => false, | 1429 | else => false, |
| 1397 | }; | 1430 | }; |
| 1398 | } | 1431 | } |
| 1399 | 1432 | ||
| 1400 | pub fn isCPtr(ty: Type, zcu: *const Zcu) bool { | 1433 | pub fn isCPtr(ty: Type, zcu: *const Zcu) bool { |
| 1401 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1434 | const ptr_info = ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }) orelse return false; |
| 1402 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, | 1435 | return ptr_info.flags.size == .c; |
| 1403 | else => false, | ||
| 1404 | }; | ||
| 1405 | } | 1436 | } |
| 1406 | 1437 | ||
| 1407 | pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool { | 1438 | pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool { |
| 1408 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1439 | const ip = &zcu.intern_pool; |
| 1440 | return ty: switch (ip.indexToKey(ty.toIntern())) { | ||
| 1409 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 1441 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1410 | .slice => false, | 1442 | .slice => false, |
| 1411 | .one, .many, .c => true, | 1443 | .one, .many, .c => true, |
| 1412 | }, | 1444 | }, |
| 1413 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | 1445 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ |
| 1446 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1447 | }, | ||
| 1448 | .opt_type => |child| opt_child: switch (ip.indexToKey(child)) { | ||
| 1414 | .ptr_type => |p| switch (p.flags.size) { | 1449 | .ptr_type => |p| switch (p.flags.size) { |
| 1415 | .slice, .c => false, | 1450 | .slice, .c => false, |
| 1416 | .many, .one => !p.flags.is_allowzero, | 1451 | .many, .one => !p.flags.is_allowzero, |
| 1417 | }, | 1452 | }, |
| 1453 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | ||
| 1454 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1455 | }, | ||
| 1418 | else => false, | 1456 | else => false, |
| 1419 | }, | 1457 | }, |
| 1420 | else => false, | 1458 | else => false, |
| ... | @@ -1429,13 +1467,20 @@ pub fn ptrAllowsZero(ty: Type, zcu: *const Zcu) bool { | ... | @@ -1429,13 +1467,20 @@ pub fn ptrAllowsZero(ty: Type, zcu: *const Zcu) bool { |
| 1429 | 1467 | ||
| 1430 | /// See also `isPtrLikeOptional`. | 1468 | /// See also `isPtrLikeOptional`. |
| 1431 | pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool { | 1469 | pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool { |
| 1432 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1470 | const ip = &zcu.intern_pool; |
| 1433 | .opt_type => |child_type| child_type == .anyerror_type or switch (zcu.intern_pool.indexToKey(child_type)) { | 1471 | return ty: switch (ip.indexToKey(ty.toIntern())) { |
| 1472 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, | ||
| 1473 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | ||
| 1474 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1475 | }, | ||
| 1476 | .opt_type => |child_type| child_type == .anyerror_type or opt_child: switch (ip.indexToKey(child_type)) { | ||
| 1434 | .ptr_type => |ptr_type| ptr_type.flags.size != .c and !ptr_type.flags.is_allowzero, | 1477 | .ptr_type => |ptr_type| ptr_type.flags.size != .c and !ptr_type.flags.is_allowzero, |
| 1478 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | ||
| 1479 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1480 | }, | ||
| 1435 | .error_set_type, .inferred_error_set_type => true, | 1481 | .error_set_type, .inferred_error_set_type => true, |
| 1436 | else => false, | 1482 | else => false, |
| 1437 | }, | 1483 | }, |
| 1438 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, | ||
| 1439 | else => false, | 1484 | else => false, |
| 1440 | }; | 1485 | }; |
| 1441 | } | 1486 | } |
| ... | @@ -1443,13 +1488,20 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool { | ... | @@ -1443,13 +1488,20 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool { |
| 1443 | /// Returns true if the type is optional and would be lowered to a single pointer | 1488 | /// Returns true if the type is optional and would be lowered to a single pointer |
| 1444 | /// address value, using 0 for null. Note that this returns true for C pointers. | 1489 | /// address value, using 0 for null. Note that this returns true for C pointers. |
| 1445 | pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool { | 1490 | pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool { |
| 1446 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1491 | const ip = &zcu.intern_pool; |
| 1492 | return ty: switch (ip.indexToKey(ty.toIntern())) { | ||
| 1447 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, | 1493 | .ptr_type => |ptr_type| ptr_type.flags.size == .c, |
| 1448 | .opt_type => |child| switch (zcu.intern_pool.indexToKey(child)) { | 1494 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ |
| 1495 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1496 | }, | ||
| 1497 | .opt_type => |child| opt_child: switch (ip.indexToKey(child)) { | ||
| 1449 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 1498 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1450 | .slice, .c => false, | 1499 | .slice, .c => false, |
| 1451 | .many, .one => !ptr_type.flags.is_allowzero, | 1500 | .many, .one => !ptr_type.flags.is_allowzero, |
| 1452 | }, | 1501 | }, |
| 1502 | .restricted_ptr_type => |restricted_ptr_type| continue :opt_child .{ | ||
| 1503 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1504 | }, | ||
| 1453 | else => false, | 1505 | else => false, |
| 1454 | }, | 1506 | }, |
| 1455 | else => false, | 1507 | else => false, |
| ... | @@ -1486,7 +1538,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type { | ... | @@ -1486,7 +1538,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type { |
| 1486 | .pointer => return ty.childType(zcu), | 1538 | .pointer => return ty.childType(zcu), |
| 1487 | .optional => { | 1539 | .optional => { |
| 1488 | const ptr_ty = ty.childType(zcu); | 1540 | const ptr_ty = ty.childType(zcu); |
| 1489 | const ptr_info = zcu.intern_pool.indexToKey(ptr_ty.toIntern()).ptr_type; | 1541 | const ptr_info = ptr_ty.ptrInfoOrNull(&zcu.intern_pool, .{ .allow_optional = false }).?; |
| 1490 | assert(ptr_info.flags.size != .c); | 1542 | assert(ptr_info.flags.size != .c); |
| 1491 | assert(!ptr_info.flags.is_allowzero); | 1543 | assert(!ptr_info.flags.is_allowzero); |
| 1492 | return .fromInterned(ptr_info.child); | 1544 | return .fromInterned(ptr_info.child); |
| ... | @@ -1508,7 +1560,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type { | ... | @@ -1508,7 +1560,7 @@ pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type { |
| 1508 | /// * `[*c]T` | 1560 | /// * `[*c]T` |
| 1509 | pub fn indexableElem(ty: Type, zcu: *const Zcu) Type { | 1561 | pub fn indexableElem(ty: Type, zcu: *const Zcu) Type { |
| 1510 | const ip = &zcu.intern_pool; | 1562 | const ip = &zcu.intern_pool; |
| 1511 | return switch (ip.indexToKey(ty.toIntern())) { | 1563 | return ty: switch (ip.indexToKey(ty.toIntern())) { |
| 1512 | inline .array_type, .vector_type => |arr| .fromInterned(arr.child), | 1564 | inline .array_type, .vector_type => |arr| .fromInterned(arr.child), |
| 1513 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 1565 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1514 | .many, .slice, .c => .fromInterned(ptr_type.child), | 1566 | .many, .slice, .c => .fromInterned(ptr_type.child), |
| ... | @@ -1517,6 +1569,9 @@ pub fn indexableElem(ty: Type, zcu: *const Zcu) Type { | ... | @@ -1517,6 +1569,9 @@ pub fn indexableElem(ty: Type, zcu: *const Zcu) Type { |
| 1517 | else => unreachable, | 1569 | else => unreachable, |
| 1518 | }, | 1570 | }, |
| 1519 | }, | 1571 | }, |
| 1572 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | ||
| 1573 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1574 | }, | ||
| 1520 | else => unreachable, | 1575 | else => unreachable, |
| 1521 | }; | 1576 | }; |
| 1522 | } | 1577 | } |
| ... | @@ -1532,12 +1587,16 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type { | ... | @@ -1532,12 +1587,16 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type { |
| 1532 | /// Asserts that the type is an optional, or a C pointer. | 1587 | /// Asserts that the type is an optional, or a C pointer. |
| 1533 | /// For C pointers this returns the type unmodified. | 1588 | /// For C pointers this returns the type unmodified. |
| 1534 | pub fn optionalChild(ty: Type, zcu: *const Zcu) Type { | 1589 | pub fn optionalChild(ty: Type, zcu: *const Zcu) Type { |
| 1535 | switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1590 | const ip = &zcu.intern_pool; |
| 1591 | ty: switch (ip.indexToKey(ty.toIntern())) { | ||
| 1536 | .opt_type => |child| return .fromInterned(child), | 1592 | .opt_type => |child| return .fromInterned(child), |
| 1537 | .ptr_type => |ptr_type| { | 1593 | .ptr_type => |ptr_type| { |
| 1538 | assert(ptr_type.flags.size == .c); | 1594 | assert(ptr_type.flags.size == .c); |
| 1539 | return ty; | 1595 | return ty; |
| 1540 | }, | 1596 | }, |
| 1597 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | ||
| 1598 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1599 | }, | ||
| 1541 | else => unreachable, | 1600 | else => unreachable, |
| 1542 | } | 1601 | } |
| 1543 | } | 1602 | } |
| ... | @@ -1755,7 +1814,8 @@ pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 { | ... | @@ -1755,7 +1814,8 @@ pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 { |
| 1755 | 1814 | ||
| 1756 | /// Asserts the type is an array, pointer or vector. | 1815 | /// Asserts the type is an array, pointer or vector. |
| 1757 | pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { | 1816 | pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { |
| 1758 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1817 | const ip = &zcu.intern_pool; |
| 1818 | return ty: switch (ip.indexToKey(ty.toIntern())) { | ||
| 1759 | .vector_type, | 1819 | .vector_type, |
| 1760 | .struct_type, | 1820 | .struct_type, |
| 1761 | .tuple_type, | 1821 | .tuple_type, |
| ... | @@ -1763,6 +1823,9 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { | ... | @@ -1763,6 +1823,9 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value { |
| 1763 | 1823 | ||
| 1764 | .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null, | 1824 | .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null, |
| 1765 | .ptr_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null, | 1825 | .ptr_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null, |
| 1826 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | ||
| 1827 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1828 | }, | ||
| 1766 | 1829 | ||
| 1767 | else => unreachable, | 1830 | else => unreachable, |
| 1768 | }; | 1831 | }; |
| ... | @@ -1851,6 +1914,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { | ... | @@ -1851,6 +1914,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { |
| 1851 | .tuple_type => unreachable, | 1914 | .tuple_type => unreachable, |
| 1852 | 1915 | ||
| 1853 | .ptr_type => unreachable, | 1916 | .ptr_type => unreachable, |
| 1917 | .restricted_ptr_type => unreachable, | ||
| 1854 | .anyframe_type => unreachable, | 1918 | .anyframe_type => unreachable, |
| 1855 | .array_type => unreachable, | 1919 | .array_type => unreachable, |
| 1856 | 1920 | ||
| ... | @@ -2021,6 +2085,7 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { | ... | @@ -2021,6 +2085,7 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { |
| 2021 | assertHasLayout(ty, zcu); | 2085 | assertHasLayout(ty, zcu); |
| 2022 | return switch (ip.indexToKey(ty.toIntern())) { | 2086 | return switch (ip.indexToKey(ty.toIntern())) { |
| 2023 | .ptr_type, | 2087 | .ptr_type, |
| 2088 | .restricted_ptr_type, // number of possible values is not known until the end of compilation, so never treated as NPV/OPV | ||
| 2024 | .error_union_type, | 2089 | .error_union_type, |
| 2025 | .func_type, | 2090 | .func_type, |
| 2026 | .anyframe_type, | 2091 | .anyframe_type, |
| ... | @@ -2829,7 +2894,7 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) | ... | @@ -2829,7 +2894,7 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) |
| 2829 | pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type { | 2894 | pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type { |
| 2830 | const zcu = pt.zcu; | 2895 | const zcu = pt.zcu; |
| 2831 | const ip = &zcu.intern_pool; | 2896 | const ip = &zcu.intern_pool; |
| 2832 | const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type; | 2897 | const ptr_info = ptr_ty.ptrInfoOrNull(ip, .{ .allow_optional = false }).?; |
| 2833 | const elem_ty: Type = switch (ptr_info.flags.size) { | 2898 | const elem_ty: Type = switch (ptr_info.flags.size) { |
| 2834 | .slice, .many, .c => .fromInterned(ptr_info.child), | 2899 | .slice, .many, .c => .fromInterned(ptr_info.child), |
| 2835 | .one => switch (ip.indexToKey(ptr_info.child)) { | 2900 | .one => switch (ip.indexToKey(ptr_info.child)) { |
| ... | @@ -2883,7 +2948,7 @@ pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error | ... | @@ -2883,7 +2948,7 @@ pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error |
| 2883 | pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator.Error!Type { | 2948 | pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator.Error!Type { |
| 2884 | const zcu = pt.zcu; | 2949 | const zcu = pt.zcu; |
| 2885 | const ip = &zcu.intern_pool; | 2950 | const ip = &zcu.intern_pool; |
| 2886 | const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type; | 2951 | const ptr_info = ptr_ty.ptrInfoOrNull(ip, .{ .allow_optional = false }).?; |
| 2887 | assert(ptr_info.flags.size == .one or ptr_info.flags.size == .c); | 2952 | assert(ptr_info.flags.size == .one or ptr_info.flags.size == .c); |
| 2888 | const aggregate_ty: Type = .fromInterned(ptr_info.child); | 2953 | const aggregate_ty: Type = .fromInterned(ptr_info.child); |
| 2889 | aggregate_ty.assertHasLayout(zcu); | 2954 | aggregate_ty.assertHasLayout(zcu); |
| ... | @@ -3011,7 +3076,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator | ... | @@ -3011,7 +3076,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator |
| 3011 | .none => switch (ip.indexToKey(aggregate_ty.toIntern())) { | 3076 | .none => switch (ip.indexToKey(aggregate_ty.toIntern())) { |
| 3012 | .tuple_type, .union_type => field_ty.abiAlignment(zcu), | 3077 | .tuple_type, .union_type => field_ty.abiAlignment(zcu), |
| 3013 | .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu), | 3078 | .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu), |
| 3014 | .ptr_type => Type.usize.abiAlignment(zcu), | 3079 | .ptr_type, .restricted_ptr_type => ptrAbiAlignment(zcu.getTarget()), |
| 3015 | else => unreachable, | 3080 | else => unreachable, |
| 3016 | }, | 3081 | }, |
| 3017 | else => |a| a, | 3082 | else => |a| a, |
| ... | @@ -3040,6 +3105,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator | ... | @@ -3040,6 +3105,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator |
| 3040 | 3105 | ||
| 3041 | pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString { | 3106 | pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString { |
| 3042 | return switch (ip.indexToKey(ty.toIntern())) { | 3107 | return switch (ip.indexToKey(ty.toIntern())) { |
| 3108 | .restricted_ptr_type => ip.loadRestrictedType(ty.toIntern()).name, | ||
| 3043 | .struct_type => ip.loadStructType(ty.toIntern()).name, | 3109 | .struct_type => ip.loadStructType(ty.toIntern()).name, |
| 3044 | .union_type => ip.loadUnionType(ty.toIntern()).name, | 3110 | .union_type => ip.loadUnionType(ty.toIntern()).name, |
| 3045 | .enum_type => ip.loadEnumType(ty.toIntern()).name, | 3111 | .enum_type => ip.loadEnumType(ty.toIntern()).name, |
| ... | @@ -3247,6 +3313,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { | ... | @@ -3247,6 +3313,7 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { |
| 3247 | switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 3313 | switch (zcu.intern_pool.indexToKey(ty.toIntern())) { |
| 3248 | .int_type, | 3314 | .int_type, |
| 3249 | .ptr_type, | 3315 | .ptr_type, |
| 3316 | .restricted_ptr_type, | ||
| 3250 | .anyframe_type, | 3317 | .anyframe_type, |
| 3251 | .simple_type, | 3318 | .simple_type, |
| 3252 | .opaque_type, | 3319 | .opaque_type, |
| ... | @@ -3315,34 +3382,34 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn | ... | @@ -3315,34 +3382,34 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn |
| 3315 | } | 3382 | } |
| 3316 | 3383 | ||
| 3317 | switch (ip.indexToKey(ty.toIntern())) { | 3384 | switch (ip.indexToKey(ty.toIntern())) { |
| 3318 | .ptr_type => try collectSubtypes(Type.fromInterned(ty.ptrInfo(zcu).child), pt, visited), | 3385 | .ptr_type => |ptr_type| try collectSubtypes(.fromInterned(ptr_type.child), pt, visited), |
| 3319 | .array_type => |array_type| try collectSubtypes(Type.fromInterned(array_type.child), pt, visited), | 3386 | .array_type => |array_type| try collectSubtypes(.fromInterned(array_type.child), pt, visited), |
| 3320 | .vector_type => |vector_type| try collectSubtypes(Type.fromInterned(vector_type.child), pt, visited), | 3387 | .vector_type => |vector_type| try collectSubtypes(.fromInterned(vector_type.child), pt, visited), |
| 3321 | .opt_type => |child| try collectSubtypes(Type.fromInterned(child), pt, visited), | 3388 | .opt_type => |child| try collectSubtypes(.fromInterned(child), pt, visited), |
| 3322 | .error_union_type => |error_union_type| { | 3389 | .error_union_type => |error_union_type| { |
| 3323 | try collectSubtypes(Type.fromInterned(error_union_type.error_set_type), pt, visited); | 3390 | try collectSubtypes(.fromInterned(error_union_type.error_set_type), pt, visited); |
| 3324 | if (error_union_type.payload_type != .generic_poison_type) { | 3391 | if (error_union_type.payload_type != .generic_poison_type) { |
| 3325 | try collectSubtypes(Type.fromInterned(error_union_type.payload_type), pt, visited); | 3392 | try collectSubtypes(.fromInterned(error_union_type.payload_type), pt, visited); |
| 3326 | } | 3393 | } |
| 3327 | }, | 3394 | }, |
| 3328 | .tuple_type => |tuple| { | 3395 | .tuple_type => |tuple| { |
| 3329 | for (tuple.types.get(ip)) |field_ty| { | 3396 | for (tuple.types.get(ip)) |field_ty| { |
| 3330 | try collectSubtypes(Type.fromInterned(field_ty), pt, visited); | 3397 | try collectSubtypes(.fromInterned(field_ty), pt, visited); |
| 3331 | } | 3398 | } |
| 3332 | }, | 3399 | }, |
| 3333 | .func_type => |fn_info| { | 3400 | .func_type => |fn_info| { |
| 3334 | const param_types = fn_info.param_types.get(&zcu.intern_pool); | 3401 | const param_types = fn_info.param_types.get(&zcu.intern_pool); |
| 3335 | for (param_types) |param_ty| { | 3402 | for (param_types) |param_ty| { |
| 3336 | if (param_ty != .generic_poison_type) { | 3403 | if (param_ty != .generic_poison_type) { |
| 3337 | try collectSubtypes(Type.fromInterned(param_ty), pt, visited); | 3404 | try collectSubtypes(.fromInterned(param_ty), pt, visited); |
| 3338 | } | 3405 | } |
| 3339 | } | 3406 | } |
| 3340 | 3407 | ||
| 3341 | if (fn_info.return_type != .generic_poison_type) { | 3408 | if (fn_info.return_type != .generic_poison_type) { |
| 3342 | try collectSubtypes(Type.fromInterned(fn_info.return_type), pt, visited); | 3409 | try collectSubtypes(.fromInterned(fn_info.return_type), pt, visited); |
| 3343 | } | 3410 | } |
| 3344 | }, | 3411 | }, |
| 3345 | .anyframe_type => |child| try collectSubtypes(Type.fromInterned(child), pt, visited), | 3412 | .anyframe_type => |child| try collectSubtypes(.fromInterned(child), pt, visited), |
| 3346 | 3413 | ||
| 3347 | // leaf types | 3414 | // leaf types |
| 3348 | .undef, | 3415 | .undef, |
| ... | @@ -3354,6 +3421,7 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn | ... | @@ -3354,6 +3421,7 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn |
| 3354 | .enum_type, | 3421 | .enum_type, |
| 3355 | .simple_type, | 3422 | .simple_type, |
| 3356 | .int_type, | 3423 | .int_type, |
| 3424 | .restricted_ptr_type, | ||
| 3357 | => {}, | 3425 | => {}, |
| 3358 | 3426 | ||
| 3359 | // values, not types | 3427 | // values, not types |
src/Zcu.zig+5-1| ... | @@ -501,6 +501,7 @@ pub const BuiltinDecl = enum { | ... | @@ -501,6 +501,7 @@ pub const BuiltinDecl = enum { |
| 501 | @"panic.copyLenMismatch", | 501 | @"panic.copyLenMismatch", |
| 502 | @"panic.memcpyAlias", | 502 | @"panic.memcpyAlias", |
| 503 | @"panic.noreturnReturned", | 503 | @"panic.noreturnReturned", |
| 504 | @"panic.corruptRestrictedPointer", | ||
| 504 | 505 | ||
| 505 | VaList, | 506 | VaList, |
| 506 | 507 | ||
| ... | @@ -588,6 +589,7 @@ pub const BuiltinDecl = enum { | ... | @@ -588,6 +589,7 @@ pub const BuiltinDecl = enum { |
| 588 | .@"panic.copyLenMismatch", | 589 | .@"panic.copyLenMismatch", |
| 589 | .@"panic.memcpyAlias", | 590 | .@"panic.memcpyAlias", |
| 590 | .@"panic.noreturnReturned", | 591 | .@"panic.noreturnReturned", |
| 592 | .@"panic.corruptRestrictedPointer", | ||
| 591 | => .func, | 593 | => .func, |
| 592 | }; | 594 | }; |
| 593 | } | 595 | } |
| ... | @@ -661,6 +663,7 @@ pub const SimplePanicId = enum { | ... | @@ -661,6 +663,7 @@ pub const SimplePanicId = enum { |
| 661 | copy_len_mismatch, | 663 | copy_len_mismatch, |
| 662 | memcpy_alias, | 664 | memcpy_alias, |
| 663 | noreturn_returned, | 665 | noreturn_returned, |
| 666 | corrupt_restricted_pointer, | ||
| 664 | 667 | ||
| 665 | pub fn toBuiltin(id: SimplePanicId) BuiltinDecl { | 668 | pub fn toBuiltin(id: SimplePanicId) BuiltinDecl { |
| 666 | return switch (id) { | 669 | return switch (id) { |
| ... | @@ -684,6 +687,7 @@ pub const SimplePanicId = enum { | ... | @@ -684,6 +687,7 @@ pub const SimplePanicId = enum { |
| 684 | .copy_len_mismatch => .@"panic.copyLenMismatch", | 687 | .copy_len_mismatch => .@"panic.copyLenMismatch", |
| 685 | .memcpy_alias => .@"panic.memcpyAlias", | 688 | .memcpy_alias => .@"panic.memcpyAlias", |
| 686 | .noreturn_returned => .@"panic.noreturnReturned", | 689 | .noreturn_returned => .@"panic.noreturnReturned", |
| 690 | .corrupt_restricted_pointer => .@"panic.corruptRestrictedPointer", | ||
| 687 | // zig fmt: on | 691 | // zig fmt: on |
| 688 | }; | 692 | }; |
| 689 | } | 693 | } |
| ... | @@ -4215,7 +4219,7 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanag | ... | @@ -4215,7 +4219,7 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanag |
| 4215 | 4219 | ||
| 4216 | // Queue any decls within this type which would be automatically analyzed. | 4220 | // Queue any decls within this type which would be automatically analyzed. |
| 4217 | // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`. | 4221 | // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`. |
| 4218 | const ns = Type.fromInterned(ty).getNamespace(zcu).unwrap().?; | 4222 | const ns = Type.fromInterned(ty).getNamespace(zcu).unwrap() orelse continue; |
| 4219 | for (zcu.namespacePtr(ns).comptime_decls.items) |cu| { | 4223 | for (zcu.namespacePtr(ns).comptime_decls.items) |cu| { |
| 4220 | // `comptime` decls are always analyzed. | 4224 | // `comptime` decls are always analyzed. |
| 4221 | const unit: AnalUnit = .wrap(.{ .@"comptime" = cu }); | 4225 | const unit: AnalUnit = .wrap(.{ .@"comptime" = cu }); |
src/codegen.zig+4| ... | @@ -281,6 +281,9 @@ pub fn generateLazySymbol( | ... | @@ -281,6 +281,9 @@ pub fn generateLazySymbol( |
| 281 | w.writeAll(tag_name) catch unreachable; | 281 | w.writeAll(tag_name) catch unreachable; |
| 282 | w.writeByte(0) catch unreachable; | 282 | w.writeByte(0) catch unreachable; |
| 283 | } | 283 | } |
| 284 | } else if (Type.fromInterned(lazy_sym.ty).unrestrictedType(zcu)) |unrestricted_ptr_ty| { | ||
| 285 | alignment.* = unrestricted_ptr_ty.abiAlignment(zcu); | ||
| 286 | try w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)); // to be filled in later | ||
| 284 | } else { | 287 | } else { |
| 285 | return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {f}", .{ | 288 | return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {f}", .{ |
| 286 | @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt), | 289 | @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt), |
| ... | @@ -325,6 +328,7 @@ pub fn generateSymbol( | ... | @@ -325,6 +328,7 @@ pub fn generateSymbol( |
| 325 | switch (ip.indexToKey(val.toIntern())) { | 328 | switch (ip.indexToKey(val.toIntern())) { |
| 326 | .int_type, | 329 | .int_type, |
| 327 | .ptr_type, | 330 | .ptr_type, |
| 331 | .restricted_ptr_type, | ||
| 328 | .array_type, | 332 | .array_type, |
| 329 | .vector_type, | 333 | .vector_type, |
| 330 | .opt_type, | 334 | .opt_type, |
src/codegen/aarch64/Select.zig+45| ... | @@ -658,6 +658,28 @@ pub fn analyze(isel: *Select, air_body: []const Air.Inst.Index) !void { | ... | @@ -658,6 +658,28 @@ pub fn analyze(isel: *Select, air_body: []const Air.Inst.Index) !void { |
| 658 | air_inst_index = air_body[air_body_index]; | 658 | air_inst_index = air_body[air_body_index]; |
| 659 | continue :air_tag air_tags[@intFromEnum(air_inst_index)]; | 659 | continue :air_tag air_tags[@intFromEnum(air_inst_index)]; |
| 660 | }, | 660 | }, |
| 661 | .unwrap_restricted, .unwrap_restricted_safe => { | ||
| 662 | const ty_op = air_data[@intFromEnum(air_inst_index)].ty_op; | ||
| 663 | |||
| 664 | maybe_noop: { | ||
| 665 | switch (isel.air.typeOf(ty_op.operand, ip).restrictedRepr(zcu)) { | ||
| 666 | .double_pointer => break :maybe_noop, | ||
| 667 | .single_pointer => {}, | ||
| 668 | } | ||
| 669 | if (true) break :maybe_noop; | ||
| 670 | if (ty_op.operand.toIndex()) |src_air_inst_index| { | ||
| 671 | if (isel.hints.get(src_air_inst_index)) |hint_vpsi| { | ||
| 672 | try isel.hints.putNoClobber(gpa, air_inst_index, hint_vpsi); | ||
| 673 | } | ||
| 674 | } | ||
| 675 | } | ||
| 676 | try isel.analyzeUse(ty_op.operand); | ||
| 677 | try isel.def_order.putNoClobber(gpa, air_inst_index, {}); | ||
| 678 | |||
| 679 | air_body_index += 1; | ||
| 680 | air_inst_index = air_body[air_body_index]; | ||
| 681 | continue :air_tag air_tags[@intFromEnum(air_inst_index)]; | ||
| 682 | }, | ||
| 661 | .struct_field_ptr, .struct_field_val => { | 683 | .struct_field_ptr, .struct_field_val => { |
| 662 | const ty_pl = air_data[@intFromEnum(air_inst_index)].ty_pl; | 684 | const ty_pl = air_data[@intFromEnum(air_inst_index)].ty_pl; |
| 663 | const extra = isel.air.extraData(Air.StructField, ty_pl.payload).data; | 685 | const extra = isel.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | @@ -5737,6 +5759,29 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -5737,6 +5759,29 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 5737 | } | 5759 | } |
| 5738 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; | 5760 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; |
| 5739 | }, | 5761 | }, |
| 5762 | .unwrap_restricted, .unwrap_restricted_safe => |air_tag| { | ||
| 5763 | if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| { | ||
| 5764 | defer dst_vi.value.deref(isel); | ||
| 5765 | const ty_op = air.data(air.inst_index).ty_op; | ||
| 5766 | const unrestricted_ty = ty_op.ty.toType(); | ||
| 5767 | const restricted_ty = isel.air.typeOf(ty_op.operand, ip); | ||
| 5768 | switch (restricted_ty.restrictedRepr(zcu)) { | ||
| 5769 | .double_pointer => { | ||
| 5770 | switch (air_tag) { | ||
| 5771 | else => unreachable, | ||
| 5772 | .unwrap_restricted => {}, | ||
| 5773 | .unwrap_restricted_safe => {}, // TODO | ||
| 5774 | } | ||
| 5775 | const ptr_vi = try isel.use(ty_op.operand); | ||
| 5776 | const ptr_mat = try ptr_vi.matReg(isel); | ||
| 5777 | _ = try dst_vi.value.load(isel, unrestricted_ty, ptr_mat.ra, .{}); | ||
| 5778 | try ptr_mat.finish(isel); | ||
| 5779 | }, | ||
| 5780 | .single_pointer => try dst_vi.value.move(isel, ty_op.operand), | ||
| 5781 | } | ||
| 5782 | } | ||
| 5783 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; | ||
| 5784 | }, | ||
| 5740 | .struct_field_ptr => { | 5785 | .struct_field_ptr => { |
| 5741 | if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| unused: { | 5786 | if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| unused: { |
| 5742 | defer dst_vi.value.deref(isel); | 5787 | defer dst_vi.value.deref(isel); |
src/codegen/c.zig+36-1| ... | @@ -896,6 +896,7 @@ pub const DeclGen = struct { | ... | @@ -896,6 +896,7 @@ pub const DeclGen = struct { |
| 896 | // types, not values | 896 | // types, not values |
| 897 | .int_type, | 897 | .int_type, |
| 898 | .ptr_type, | 898 | .ptr_type, |
| 899 | .restricted_ptr_type, | ||
| 899 | .array_type, | 900 | .array_type, |
| 900 | .vector_type, | 901 | .vector_type, |
| 901 | .opt_type, | 902 | .opt_type, |
| ... | @@ -1334,7 +1335,7 @@ pub const DeclGen = struct { | ... | @@ -1334,7 +1335,7 @@ pub const DeclGen = struct { |
| 1334 | return w.writeByte(')'); | 1335 | return w.writeByte(')'); |
| 1335 | }, | 1336 | }, |
| 1336 | .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"), | 1337 | .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"), |
| 1337 | else => switch (ip.indexToKey(ty.toIntern())) { | 1338 | else => ty: switch (ip.indexToKey(ty.toIntern())) { |
| 1338 | .simple_type, // anyerror, c_char (etc), usize, isize | 1339 | .simple_type, // anyerror, c_char (etc), usize, isize |
| 1339 | .int_type, | 1340 | .int_type, |
| 1340 | .enum_type, | 1341 | .enum_type, |
| ... | @@ -1405,6 +1406,9 @@ pub const DeclGen = struct { | ... | @@ -1405,6 +1406,9 @@ pub const DeclGen = struct { |
| 1405 | try w.writeByte('}'); | 1406 | try w.writeByte('}'); |
| 1406 | }, | 1407 | }, |
| 1407 | }, | 1408 | }, |
| 1409 | .restricted_ptr_type => |restricted_ptr_type| continue :ty .{ | ||
| 1410 | .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type, | ||
| 1411 | }, | ||
| 1408 | .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) { | 1412 | .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) { |
| 1409 | .npv_payload => unreachable, // opv optional | 1413 | .npv_payload => unreachable, // opv optional |
| 1410 | 1414 | ||
| ... | @@ -2840,6 +2844,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { | ... | @@ -2840,6 +2844,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 2840 | .set_err_return_trace => try airSetErrReturnTrace(f, inst), | 2844 | .set_err_return_trace => try airSetErrReturnTrace(f, inst), |
| 2841 | .save_err_return_trace_index => try airSaveErrReturnTraceIndex(f, inst), | 2845 | .save_err_return_trace_index => try airSaveErrReturnTraceIndex(f, inst), |
| 2842 | 2846 | ||
| 2847 | .unwrap_restricted => try airUnwrapRestricted(f, inst, false), | ||
| 2848 | .unwrap_restricted_safe => try airUnwrapRestricted(f, inst, true), | ||
| 2849 | |||
| 2843 | .wasm_memory_size => try airWasmMemorySize(f, inst), | 2850 | .wasm_memory_size => try airWasmMemorySize(f, inst), |
| 2844 | .wasm_memory_grow => try airWasmMemoryGrow(f, inst), | 2851 | .wasm_memory_grow => try airWasmMemoryGrow(f, inst), |
| 2845 | 2852 | ||
| ... | @@ -5533,6 +5540,34 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5533,6 +5540,34 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5533 | return local; | 5540 | return local; |
| 5534 | } | 5541 | } |
| 5535 | 5542 | ||
| 5543 | fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ||
| 5544 | const pt = f.dg.pt; | ||
| 5545 | const zcu = pt.zcu; | ||
| 5546 | const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | ||
| 5547 | |||
| 5548 | const unrestricted_ty = ty_op.ty.toType(); | ||
| 5549 | const restricted_ty = f.typeOf(ty_op.operand); | ||
| 5550 | const operand = try f.resolveInst(ty_op.operand); | ||
| 5551 | try reap(f, inst, &.{ty_op.operand}); | ||
| 5552 | |||
| 5553 | const w = &f.code.writer; | ||
| 5554 | const local = try f.allocLocal(inst, unrestricted_ty); | ||
| 5555 | |||
| 5556 | try f.writeCValue(w, local, .other); | ||
| 5557 | try w.writeAll(" = "); | ||
| 5558 | switch (restricted_ty.restrictedRepr(zcu)) { | ||
| 5559 | .double_pointer => { | ||
| 5560 | _ = safety; // TODO | ||
| 5561 | try f.writeCValueDeref(w, operand); | ||
| 5562 | }, | ||
| 5563 | .single_pointer => try f.writeCValue(w, operand, .other), | ||
| 5564 | } | ||
| 5565 | try w.writeByte(';'); | ||
| 5566 | try f.newline(); | ||
| 5567 | |||
| 5568 | return local; | ||
| 5569 | } | ||
| 5570 | |||
| 5536 | fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | 5571 | fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5537 | const pt = f.dg.pt; | 5572 | const pt = f.dg.pt; |
| 5538 | const w = &f.code.writer; | 5573 | const w = &f.code.writer; |
src/codegen/c/type.zig+19-1| ... | @@ -284,6 +284,20 @@ pub const CType = union(enum) { | ... | @@ -284,6 +284,20 @@ pub const CType = union(enum) { |
| 284 | 284 | ||
| 285 | .pointer => { | 285 | .pointer => { |
| 286 | const ptr = cur_ty.ptrInfo(zcu); | 286 | const ptr = cur_ty.ptrInfo(zcu); |
| 287 | if (cur_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (cur_ty.restrictedRepr(zcu)) { | ||
| 288 | .double_pointer => { | ||
| 289 | const unrestricted_cty = try lowerInner(unrestricted_ty, true, deps, arena, zcu); | ||
| 290 | const unrestricted_cty_buf = try arena.create(CType); | ||
| 291 | unrestricted_cty_buf.* = unrestricted_cty; | ||
| 292 | return .{ .pointer = .{ | ||
| 293 | .@"const" = true, | ||
| 294 | .@"volatile" = false, | ||
| 295 | .elem_ty = unrestricted_cty_buf, | ||
| 296 | .nonstring = false, | ||
| 297 | } }; | ||
| 298 | }, | ||
| 299 | .single_pointer => {}, | ||
| 300 | }; | ||
| 287 | switch (ptr.flags.size) { | 301 | switch (ptr.flags.size) { |
| 288 | .slice => { | 302 | .slice => { |
| 289 | try deps.addType(gpa, cur_ty, allow_incomplete); | 303 | try deps.addType(gpa, cur_ty, allow_incomplete); |
| ... | @@ -912,7 +926,10 @@ pub const CType = union(enum) { | ... | @@ -912,7 +926,10 @@ pub const CType = union(enum) { |
| 912 | .optional => try w.print("opt_{f}", .{fmtZigType(ty.optionalChild(zcu), zcu)}), | 926 | .optional => try w.print("opt_{f}", .{fmtZigType(ty.optionalChild(zcu), zcu)}), |
| 913 | .error_union => try w.print("errunion_{f}", .{fmtZigType(ty.errorUnionPayload(zcu), zcu)}), | 927 | .error_union => try w.print("errunion_{f}", .{fmtZigType(ty.errorUnionPayload(zcu), zcu)}), |
| 914 | 928 | ||
| 915 | .pointer => switch (ty.ptrSize(zcu)) { | 929 | .pointer => if (ty.unrestrictedType(zcu)) |_| { |
| 930 | const name = ty.containerTypeName(ip).toSlice(ip); | ||
| 931 | try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)}); | ||
| 932 | } else switch (ty.ptrSize(zcu)) { | ||
| 916 | .one, .many, .c => try w.print("ptr_{f}", .{fmtZigType(ty.childType(zcu), zcu)}), | 933 | .one, .many, .c => try w.print("ptr_{f}", .{fmtZigType(ty.childType(zcu), zcu)}), |
| 917 | .slice => try w.print("slice_{f}", .{fmtZigType(ty.childType(zcu), zcu)}), | 934 | .slice => try w.print("slice_{f}", .{fmtZigType(ty.childType(zcu), zcu)}), |
| 918 | }, | 935 | }, |
| ... | @@ -985,6 +1002,7 @@ pub const CType = union(enum) { | ... | @@ -985,6 +1002,7 @@ pub const CType = union(enum) { |
| 985 | return switch (ip.indexToKey(ty.toIntern())) { | 1002 | return switch (ip.indexToKey(ty.toIntern())) { |
| 986 | .int_type, | 1003 | .int_type, |
| 987 | .ptr_type, | 1004 | .ptr_type, |
| 1005 | .restricted_ptr_type, | ||
| 988 | .anyframe_type, | 1006 | .anyframe_type, |
| 989 | .simple_type, | 1007 | .simple_type, |
| 990 | .opaque_type, | 1008 | .opaque_type, |
src/codegen/llvm.zig+2| ... | @@ -3061,6 +3061,7 @@ pub const Object = struct { | ... | @@ -3061,6 +3061,7 @@ pub const Object = struct { |
| 3061 | }), | 3061 | }), |
| 3062 | }; | 3062 | }; |
| 3063 | }, | 3063 | }, |
| 3064 | .restricted_ptr_type => @panic("TODO implement restricted pointers"), | ||
| 3064 | .array_type => |array_type| o.builder.arrayType( | 3065 | .array_type => |array_type| o.builder.arrayType( |
| 3065 | array_type.lenIncludingSentinel(), | 3066 | array_type.lenIncludingSentinel(), |
| 3066 | try o.lowerType(.fromInterned(array_type.child)), | 3067 | try o.lowerType(.fromInterned(array_type.child)), |
| ... | @@ -3443,6 +3444,7 @@ pub const Object = struct { | ... | @@ -3443,6 +3444,7 @@ pub const Object = struct { |
| 3443 | return switch (val_key) { | 3444 | return switch (val_key) { |
| 3444 | .int_type, | 3445 | .int_type, |
| 3445 | .ptr_type, | 3446 | .ptr_type, |
| 3447 | .restricted_ptr_type, | ||
| 3446 | .array_type, | 3448 | .array_type, |
| 3447 | .vector_type, | 3449 | .vector_type, |
| 3448 | .opt_type, | 3450 | .opt_type, |
src/codegen/llvm/FuncGen.zig+19| ... | @@ -413,6 +413,9 @@ pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air | ... | @@ -413,6 +413,9 @@ pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air |
| 413 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(body[i..]), | 413 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(body[i..]), |
| 414 | .wrap_errunion_err => try self.airWrapErrUnionErr(body[i..]), | 414 | .wrap_errunion_err => try self.airWrapErrUnionErr(body[i..]), |
| 415 | 415 | ||
| 416 | .unwrap_restricted => try self.airUnwrapRestricted(inst, false), | ||
| 417 | .unwrap_restricted_safe => try self.airUnwrapRestricted(inst, true), | ||
| 418 | |||
| 416 | .wasm_memory_size => try self.airWasmMemorySize(inst), | 419 | .wasm_memory_size => try self.airWasmMemorySize(inst), |
| 417 | .wasm_memory_grow => try self.airWasmMemoryGrow(inst), | 420 | .wasm_memory_grow => try self.airWasmMemoryGrow(inst), |
| 418 | 421 | ||
| ... | @@ -3250,6 +3253,22 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocat | ... | @@ -3250,6 +3253,22 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocat |
| 3250 | return result_ptr; | 3253 | return result_ptr; |
| 3251 | } | 3254 | } |
| 3252 | 3255 | ||
| 3256 | fn airUnwrapRestricted(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value { | ||
| 3257 | const o = self.object; | ||
| 3258 | const zcu = o.zcu; | ||
| 3259 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | ||
| 3260 | const unrestricted_ty = ty_op.ty.toType(); | ||
| 3261 | const restricted_ty = self.typeOf(ty_op.operand); | ||
| 3262 | const operand = try self.resolveInst(ty_op.operand); | ||
| 3263 | switch (restricted_ty.restrictedRepr(zcu)) { | ||
| 3264 | .double_pointer => { | ||
| 3265 | _ = safety; // TODO | ||
| 3266 | return self.wip.load(.normal, .ptr, operand, unrestricted_ty.abiAlignment(zcu).toLlvm(), "restricted.unwrap"); | ||
| 3267 | }, | ||
| 3268 | .single_pointer => return operand, | ||
| 3269 | } | ||
| 3270 | } | ||
| 3271 | |||
| 3253 | fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 3272 | fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3254 | const o = self.object; | 3273 | const o = self.object; |
| 3255 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 3274 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
src/codegen/riscv64/CodeGen.zig+4| ... | @@ -1614,6 +1614,10 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1614,6 +1614,10 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1614 | .wrap_errunion_payload => try func.airWrapErrUnionPayload(inst), | 1614 | .wrap_errunion_payload => try func.airWrapErrUnionPayload(inst), |
| 1615 | .wrap_errunion_err => try func.airWrapErrUnionErr(inst), | 1615 | .wrap_errunion_err => try func.airWrapErrUnionErr(inst), |
| 1616 | 1616 | ||
| 1617 | .unwrap_restricted, | ||
| 1618 | .unwrap_restricted_safe, | ||
| 1619 | => return func.fail("TODO implement restricted pointers", .{}), | ||
| 1620 | |||
| 1617 | .runtime_nav_ptr => try func.airRuntimeNavPtr(inst), | 1621 | .runtime_nav_ptr => try func.airRuntimeNavPtr(inst), |
| 1618 | 1622 | ||
| 1619 | .add_optimized, | 1623 | .add_optimized, |
src/codegen/sparc64/CodeGen.zig+4| ... | @@ -676,6 +676,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -676,6 +676,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 676 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), | 676 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 677 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), | 677 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 678 | 678 | ||
| 679 | .unwrap_restricted, | ||
| 680 | .unwrap_restricted_safe, | ||
| 681 | => return self.fail("TODO implement restricted pointers", .{}), | ||
| 682 | |||
| 679 | .add_optimized, | 683 | .add_optimized, |
| 680 | .sub_optimized, | 684 | .sub_optimized, |
| 681 | .mul_optimized, | 685 | .mul_optimized, |
src/codegen/spirv/CodeGen.zig+4-1| ... | @@ -774,6 +774,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id { | ... | @@ -774,6 +774,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id { |
| 774 | switch (ip.indexToKey(val.toIntern())) { | 774 | switch (ip.indexToKey(val.toIntern())) { |
| 775 | .int_type, | 775 | .int_type, |
| 776 | .ptr_type, | 776 | .ptr_type, |
| 777 | .restricted_ptr_type, | ||
| 777 | .array_type, | 778 | .array_type, |
| 778 | .vector_type, | 779 | .vector_type, |
| 779 | .opt_type, | 780 | .opt_type, |
| ... | @@ -2774,7 +2775,9 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) Error!void { | ... | @@ -2774,7 +2775,9 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) Error!void { |
| 2774 | .unwrap_errunion_err => try cg.airErrUnionErr(inst), | 2775 | .unwrap_errunion_err => try cg.airErrUnionErr(inst), |
| 2775 | .unwrap_errunion_payload => try cg.airErrUnionPayload(inst), | 2776 | .unwrap_errunion_payload => try cg.airErrUnionPayload(inst), |
| 2776 | .wrap_errunion_err => try cg.airWrapErrUnionErr(inst), | 2777 | .wrap_errunion_err => try cg.airWrapErrUnionErr(inst), |
| 2777 | .wrap_errunion_payload => try cg.airWrapErrUnionPayload(inst), | 2778 | .wrap_errunion_payload => try cg.airWrapErrUnionPayload(inst), |
| 2779 | |||
| 2780 | .unwrap_restricted => return cg.fail("TODO implement restricted pointers", .{}), | ||
| 2778 | 2781 | ||
| 2779 | .is_null => try cg.airIsNull(inst, false, .is_null), | 2782 | .is_null => try cg.airIsNull(inst, false, .is_null), |
| 2780 | .is_non_null => try cg.airIsNull(inst, false, .is_non_null), | 2783 | .is_non_null => try cg.airIsNull(inst, false, .is_non_null), |
src/codegen/wasm/CodeGen.zig+20| ... | @@ -1815,6 +1815,9 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1815,6 +1815,9 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1815 | .errunion_payload_ptr_set => cg.airErrUnionPayloadPtrSet(inst), | 1815 | .errunion_payload_ptr_set => cg.airErrUnionPayloadPtrSet(inst), |
| 1816 | .error_name => cg.airErrorName(inst), | 1816 | .error_name => cg.airErrorName(inst), |
| 1817 | 1817 | ||
| 1818 | .unwrap_restricted => cg.airUnwrapRestricted(inst, false), | ||
| 1819 | .unwrap_restricted_safe => cg.airUnwrapRestricted(inst, true), | ||
| 1820 | |||
| 1818 | .wasm_memory_size => cg.airWasmMemorySize(inst), | 1821 | .wasm_memory_size => cg.airWasmMemorySize(inst), |
| 1819 | .wasm_memory_grow => cg.airWasmMemoryGrow(inst), | 1822 | .wasm_memory_grow => cg.airWasmMemoryGrow(inst), |
| 1820 | 1823 | ||
| ... | @@ -4676,6 +4679,7 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { | ... | @@ -4676,6 +4679,7 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { |
| 4676 | switch (ip.indexToKey(val.ip_index)) { | 4679 | switch (ip.indexToKey(val.ip_index)) { |
| 4677 | .int_type, | 4680 | .int_type, |
| 4678 | .ptr_type, | 4681 | .ptr_type, |
| 4682 | .restricted_ptr_type, | ||
| 4679 | .array_type, | 4683 | .array_type, |
| 4680 | .vector_type, | 4684 | .vector_type, |
| 4681 | .opt_type, | 4685 | .opt_type, |
| ... | @@ -6719,6 +6723,22 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void | ... | @@ -6719,6 +6723,22 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 6719 | return cg.finishAir(inst, result, &.{ty_op.operand}); | 6723 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| 6720 | } | 6724 | } |
| 6721 | 6725 | ||
| 6726 | fn airUnwrapRestricted(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { | ||
| 6727 | const zcu = cg.pt.zcu; | ||
| 6728 | const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | ||
| 6729 | const operand = try cg.resolveInst(ty_op.operand); | ||
| 6730 | const unrestricted_ty = ty_op.ty.toType(); | ||
| 6731 | const restricted_ty = cg.typeOf(ty_op.operand); | ||
| 6732 | const result = result: switch (restricted_ty.restrictedRepr(zcu)) { | ||
| 6733 | .double_pointer => { | ||
| 6734 | _ = safety; // TODO | ||
| 6735 | break :result try cg.load(operand, unrestricted_ty, 0); | ||
| 6736 | }, | ||
| 6737 | .single_pointer => cg.reuseOperand(ty_op.operand, operand), | ||
| 6738 | }; | ||
| 6739 | return cg.finishAir(inst, result, &.{ty_op.operand}); | ||
| 6740 | } | ||
| 6741 | |||
| 6722 | fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6742 | fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6723 | const pt = cg.pt; | 6743 | const pt = cg.pt; |
| 6724 | const zcu = pt.zcu; | 6744 | const zcu = pt.zcu; |
src/codegen/x86_64/CodeGen.zig+153-13| ... | @@ -103829,6 +103829,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -103829,6 +103829,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 103829 | try eu.write(&ops[0], .{ .disp = eu_err_off }, cg); | 103829 | try eu.write(&ops[0], .{ .disp = eu_err_off }, cg); |
| 103830 | try eu.finish(inst, &.{ty_op.operand}, &ops, cg); | 103830 | try eu.finish(inst, &.{ty_op.operand}, &ops, cg); |
| 103831 | }, | 103831 | }, |
| 103832 | .unwrap_restricted, .unwrap_restricted_safe => |air_tag| { | ||
| 103833 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | ||
| 103834 | const unrestricted_ty = ty_op.ty.toType(); | ||
| 103835 | const restricted_ty = cg.typeOf(ty_op.operand); | ||
| 103836 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | ||
| 103837 | const res = res: switch (restricted_ty.restrictedRepr(zcu)) { | ||
| 103838 | .double_pointer => { | ||
| 103839 | switch (air_tag) { | ||
| 103840 | else => unreachable, | ||
| 103841 | .unwrap_restricted => {}, | ||
| 103842 | .unwrap_restricted_safe => cg.select(&.{}, &.{}, &ops, &.{ .{ | ||
| 103843 | .required_features = .{ .avx, null, null, null }, | ||
| 103844 | .patterns = &.{ | ||
| 103845 | .{ .src = .{ .mem, .none, .none } }, | ||
| 103846 | .{ .src = .{ .to_gpr, .none, .none } }, | ||
| 103847 | }, | ||
| 103848 | .call_frame = .{ .alignment = .@"32" }, | ||
| 103849 | .extra_temps = .{ | ||
| 103850 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | ||
| 103851 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } }, | ||
| 103852 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | ||
| 103853 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | ||
| 103854 | .unused, | ||
| 103855 | .unused, | ||
| 103856 | .unused, | ||
| 103857 | .unused, | ||
| 103858 | .unused, | ||
| 103859 | .unused, | ||
| 103860 | .unused, | ||
| 103861 | }, | ||
| 103862 | .clobbers = .{ .eflags = true }, | ||
| 103863 | .each = .{ .once = &.{ | ||
| 103864 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | ||
| 103865 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | ||
| 103866 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | ||
| 103867 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | ||
| 103868 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | ||
| 103869 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | ||
| 103870 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | ||
| 103871 | } }, | ||
| 103872 | }, .{ | ||
| 103873 | .required_features = .{ .sse, null, null, null }, | ||
| 103874 | .patterns = &.{ | ||
| 103875 | .{ .src = .{ .mem, .none, .none } }, | ||
| 103876 | .{ .src = .{ .to_gpr, .none, .none } }, | ||
| 103877 | }, | ||
| 103878 | .call_frame = .{ .alignment = .@"16" }, | ||
| 103879 | .extra_temps = .{ | ||
| 103880 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | ||
| 103881 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } }, | ||
| 103882 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | ||
| 103883 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | ||
| 103884 | .unused, | ||
| 103885 | .unused, | ||
| 103886 | .unused, | ||
| 103887 | .unused, | ||
| 103888 | .unused, | ||
| 103889 | .unused, | ||
| 103890 | .unused, | ||
| 103891 | }, | ||
| 103892 | .clobbers = .{ .eflags = true }, | ||
| 103893 | .each = .{ .once = &.{ | ||
| 103894 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | ||
| 103895 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | ||
| 103896 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | ||
| 103897 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | ||
| 103898 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | ||
| 103899 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | ||
| 103900 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | ||
| 103901 | } }, | ||
| 103902 | }, .{ | ||
| 103903 | .patterns = &.{ | ||
| 103904 | .{ .src = .{ .mem, .none, .none } }, | ||
| 103905 | .{ .src = .{ .to_gpr, .none, .none } }, | ||
| 103906 | }, | ||
| 103907 | .call_frame = .{ .alignment = .@"8" }, | ||
| 103908 | .extra_temps = .{ | ||
| 103909 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | ||
| 103910 | .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } }, | ||
| 103911 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | ||
| 103912 | .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } }, | ||
| 103913 | .unused, | ||
| 103914 | .unused, | ||
| 103915 | .unused, | ||
| 103916 | .unused, | ||
| 103917 | .unused, | ||
| 103918 | .unused, | ||
| 103919 | .unused, | ||
| 103920 | }, | ||
| 103921 | .clobbers = .{ .eflags = true }, | ||
| 103922 | .each = .{ .once = &.{ | ||
| 103923 | .{ ._, ._, .lea, .tmp0p, .leaa(.tmp1, .add_ptr_size), ._, ._ }, | ||
| 103924 | .{ ._, ._, .mov, .tmp2p, .src0p, ._, ._ }, | ||
| 103925 | .{ ._, ._, .sub, .tmp2p, .tmp0p, ._, ._ }, | ||
| 103926 | .{ ._, ._r, .ro, .tmp2p, .sa(.none, .add_log2_ptr_size), ._, ._ }, | ||
| 103927 | .{ ._, ._, .cmp, .tmp2p, .leaa(.tmp0p, .sub_ptr_size), ._, ._ }, | ||
| 103928 | .{ ._, ._b, .j, .@"0f", ._, ._, ._ }, | ||
| 103929 | .{ ._, ._, .call, .tmp3d, ._, ._, ._ }, | ||
| 103930 | } }, | ||
| 103931 | } }) catch |err| switch (err) { | ||
| 103932 | error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{ | ||
| 103933 | @tagName(air_tag), | ||
| 103934 | unrestricted_ty.fmt(pt), | ||
| 103935 | restricted_ty.fmt(pt), | ||
| 103936 | ops[0].tracking(cg), | ||
| 103937 | }), | ||
| 103938 | else => |e| return e, | ||
| 103939 | }, | ||
| 103940 | } | ||
| 103941 | break :res try ops[0].load(unrestricted_ty, .{}, cg); | ||
| 103942 | }, | ||
| 103943 | .single_pointer => ops[0], | ||
| 103944 | }; | ||
| 103945 | try res.finish(inst, &.{ty_op.operand}, &ops, cg); | ||
| 103946 | }, | ||
| 103832 | .struct_field_ptr => { | 103947 | .struct_field_ptr => { |
| 103833 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | 103948 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 103834 | const struct_field = cg.air.extraData(Air.StructField, ty_pl.payload).data; | 103949 | const struct_field = cg.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | @@ -176216,20 +176331,22 @@ fn genCall(self: *CodeGen, info: union(enum) { | ... | @@ -176216,20 +176331,22 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 176216 | // Due to incremental compilation, how function calls are generated depends | 176331 | // Due to incremental compilation, how function calls are generated depends |
| 176217 | // on linking. | 176332 | // on linking. |
| 176218 | switch (info) { | 176333 | switch (info) { |
| 176219 | .air => |callee| if (callee.toInterned()) |func_ip_index| { | 176334 | .air => |callee| if (callee.toInterned()) |func_ip_index| try self.asmImmediate( |
| 176220 | const func_key = ip.indexToKey(func_ip_index); | 176335 | .{ ._, .call }, |
| 176221 | switch (switch (func_key) { | 176336 | switch (switch (ip.indexToKey(func_ip_index)) { |
| 176222 | else => func_key, | 176337 | else => |func_key| func_key, |
| 176223 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { | 176338 | .ptr => |ptr| switch (ptr.byte_offset) { |
| 176224 | .nav => |nav| ip.indexToKey(zcu.navValue(nav).toIntern()), | 176339 | 0 => switch (ptr.base_addr) { |
| 176225 | else => func_key, | 176340 | .nav => |nav| ip.indexToKey(zcu.navValue(nav).toIntern()), |
| 176226 | } else func_key, | 176341 | else => unreachable, |
| 176342 | }, | ||
| 176343 | else => unreachable, | ||
| 176344 | }, | ||
| 176227 | }) { | 176345 | }) { |
| 176228 | else => unreachable, | 176346 | else => unreachable, |
| 176229 | .func => |func| try self.asmImmediate(.{ ._, .call }, .{ .nav = .{ .index = func.owner_nav } }), | 176347 | inline .func, .@"extern" => |func| .{ .nav = .{ .index = func.owner_nav } }, |
| 176230 | .@"extern" => |@"extern"| try self.asmImmediate(.{ ._, .call }, .{ .nav = .{ .index = @"extern".owner_nav } }), | 176348 | }, |
| 176231 | } | 176349 | ) else { |
| 176232 | } else { | ||
| 176233 | assert(self.typeOf(callee).zigTypeTag(zcu) == .pointer); | 176350 | assert(self.typeOf(callee).zigTypeTag(zcu) == .pointer); |
| 176234 | const scratch_reg = abi.getCAbiLinkerScratchReg(fn_info.cc); | 176351 | const scratch_reg = abi.getCAbiLinkerScratchReg(fn_info.cc); |
| 176235 | try self.genSetReg(scratch_reg, .usize, .{ .air_ref = callee }, .{}); | 176352 | try self.genSetReg(scratch_reg, .usize, .{ .air_ref = callee }, .{}); |
| ... | @@ -188525,6 +188642,7 @@ const Select = struct { | ... | @@ -188525,6 +188642,7 @@ const Select = struct { |
| 188525 | splat_float_mem: struct { ref: Select.Operand.Ref, inside: enum { zero } = .zero, outside: f16 }, | 188642 | splat_float_mem: struct { ref: Select.Operand.Ref, inside: enum { zero } = .zero, outside: f16 }, |
| 188526 | frame: FrameIndex, | 188643 | frame: FrameIndex, |
| 188527 | lazy_sym: struct { kind: link.File.LazySymbol.Kind, ref: Select.Operand.Ref = .none }, | 188644 | lazy_sym: struct { kind: link.File.LazySymbol.Kind, ref: Select.Operand.Ref = .none }, |
| 188645 | panic_func: Zcu.SimplePanicId, | ||
| 188528 | extern_func: [*:0]const u8, | 188646 | extern_func: [*:0]const u8, |
| 188529 | 188647 | ||
| 188530 | const ConstSpec = struct { | 188648 | const ConstSpec = struct { |
| ... | @@ -188986,7 +189104,25 @@ const Select = struct { | ... | @@ -188986,7 +189104,25 @@ const Select = struct { |
| 188986 | }, | 189104 | }, |
| 188987 | } }), true }; | 189105 | } }), true }; |
| 188988 | }, | 189106 | }, |
| 188989 | .extern_func => |extern_func_spec| .{ try cg.tempInit(spec.type, .{ .lea_extern_func = try cg.addString(std.mem.span(extern_func_spec)) }), true }, | 189107 | .panic_func => |panic_id| .{ try cg.tempInit( |
| 189108 | spec.type, | ||
| 189109 | switch (switch (pt.zcu.intern_pool.indexToKey(pt.zcu.builtin_decl_values.get(panic_id.toBuiltin()))) { | ||
| 189110 | else => |func_key| func_key, | ||
| 189111 | .ptr => |ptr| switch (ptr.byte_offset) { | ||
| 189112 | 0 => switch (ptr.base_addr) { | ||
| 189113 | .nav => |nav| pt.zcu.intern_pool.indexToKey(pt.zcu.navValue(nav).toIntern()), | ||
| 189114 | else => unreachable, | ||
| 189115 | }, | ||
| 189116 | else => unreachable, | ||
| 189117 | }, | ||
| 189118 | }) { | ||
| 189119 | else => unreachable, | ||
| 189120 | inline .func, .@"extern" => |func| .{ .lea_nav = func.owner_nav }, | ||
| 189121 | }, | ||
| 189122 | ), true }, | ||
| 189123 | .extern_func => |extern_func_spec| .{ try cg.tempInit(spec.type, .{ | ||
| 189124 | .lea_extern_func = try cg.addString(std.mem.span(extern_func_spec)), | ||
| 189125 | }), true }, | ||
| 188990 | }; | 189126 | }; |
| 188991 | } | 189127 | } |
| 188992 | 189128 | ||
| ... | @@ -189036,6 +189172,7 @@ const Select = struct { | ... | @@ -189036,6 +189172,7 @@ const Select = struct { |
| 189036 | lhs: enum(u6) { | 189172 | lhs: enum(u6) { |
| 189037 | none, | 189173 | none, |
| 189038 | ptr_size, | 189174 | ptr_size, |
| 189175 | log2_ptr_size, | ||
| 189039 | ptr_bit_size, | 189176 | ptr_bit_size, |
| 189040 | size, | 189177 | size, |
| 189041 | src0_size, | 189178 | src0_size, |
| ... | @@ -189072,7 +189209,9 @@ const Select = struct { | ... | @@ -189072,7 +189209,9 @@ const Select = struct { |
| 189072 | rhs: Memory.Scale, | 189209 | rhs: Memory.Scale, |
| 189073 | 189210 | ||
| 189074 | const none: Adjust = .{ .sign = .pos, .lhs = .none, .op = .mul, .rhs = .@"1" }; | 189211 | const none: Adjust = .{ .sign = .pos, .lhs = .none, .op = .mul, .rhs = .@"1" }; |
| 189212 | const add_ptr_size: Adjust = .{ .sign = .pos, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" }; | ||
| 189075 | const sub_ptr_size: Adjust = .{ .sign = .neg, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" }; | 189213 | const sub_ptr_size: Adjust = .{ .sign = .neg, .lhs = .ptr_size, .op = .mul, .rhs = .@"1" }; |
| 189214 | const add_log2_ptr_size: Adjust = .{ .sign = .pos, .lhs = .log2_ptr_size, .op = .mul, .rhs = .@"1" }; | ||
| 189076 | const add_ptr_bit_size: Adjust = .{ .sign = .pos, .lhs = .ptr_bit_size, .op = .mul, .rhs = .@"1" }; | 189215 | const add_ptr_bit_size: Adjust = .{ .sign = .pos, .lhs = .ptr_bit_size, .op = .mul, .rhs = .@"1" }; |
| 189077 | const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" }; | 189216 | const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" }; |
| 189078 | const add_size_div_4: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"4" }; | 189217 | const add_size_div_4: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"4" }; |
| ... | @@ -190013,6 +190152,7 @@ const Select = struct { | ... | @@ -190013,6 +190152,7 @@ const Select = struct { |
| 190013 | const lhs: SignedImm = lhs: switch (op.flags.adjust.lhs) { | 190152 | const lhs: SignedImm = lhs: switch (op.flags.adjust.lhs) { |
| 190014 | .none => 0, | 190153 | .none => 0, |
| 190015 | .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8), | 190154 | .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8), |
| 190155 | .log2_ptr_size => std.math.log2(@divExact(s.cg.target.ptrBitWidth(), 8)), | ||
| 190016 | .ptr_bit_size => s.cg.target.ptrBitWidth(), | 190156 | .ptr_bit_size => s.cg.target.ptrBitWidth(), |
| 190017 | .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)), | 190157 | .size => @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu)), |
| 190018 | .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)), | 190158 | .src0_size => @intCast(Select.Operand.Ref.src0.typeOf(s).abiSize(s.cg.pt.zcu)), |
src/link/Dwarf.zig+9-1| ... | @@ -3060,6 +3060,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -3060,6 +3060,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3060 | } = switch (ip.indexToKey(nav_val.toIntern())) { | 3060 | } = switch (ip.indexToKey(nav_val.toIntern())) { |
| 3061 | .int_type, | 3061 | .int_type, |
| 3062 | .ptr_type, | 3062 | .ptr_type, |
| 3063 | .restricted_ptr_type, | ||
| 3063 | .array_type, | 3064 | .array_type, |
| 3064 | .vector_type, | 3065 | .vector_type, |
| 3065 | .opt_type, | 3066 | .opt_type, |
| ... | @@ -3566,7 +3567,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -3566,7 +3567,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3566 | 3567 | ||
| 3567 | const diw = &wip_nav.debug_info.writer; | 3568 | const diw = &wip_nav.debug_info.writer; |
| 3568 | var big_int_space: Value.BigIntSpace = undefined; | 3569 | var big_int_space: Value.BigIntSpace = undefined; |
| 3569 | switch (value_ip_key) { | 3570 | key: switch (value_ip_key) { |
| 3570 | .func => unreachable, // handled above | 3571 | .func => unreachable, // handled above |
| 3571 | .@"extern" => unreachable, // handled above | 3572 | .@"extern" => unreachable, // handled above |
| 3572 | 3573 | ||
| ... | @@ -3629,6 +3630,13 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -3629,6 +3630,13 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3629 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); | 3630 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 3630 | }, | 3631 | }, |
| 3631 | }, | 3632 | }, |
| 3633 | .restricted_ptr_type => |restricted_ptr_type| switch (Type.restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu)) { | ||
| 3634 | .double_pointer => continue :key .{ .ptr_type = .{ | ||
| 3635 | .child = restricted_ptr_type.unrestricted_ptr_type, | ||
| 3636 | .flags = .{ .is_const = true }, | ||
| 3637 | } }, | ||
| 3638 | .single_pointer => continue :key .{ .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type }, | ||
| 3639 | }, | ||
| 3632 | .array_type => |array_type| { | 3640 | .array_type => |array_type| { |
| 3633 | const array_child_type: Type = .fromInterned(array_type.child); | 3641 | const array_child_type: Type = .fromInterned(array_type.child); |
| 3634 | try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type); | 3642 | try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type); |
src/print_value.zig+1| ... | @@ -49,6 +49,7 @@ pub fn print( | ... | @@ -49,6 +49,7 @@ pub fn print( |
| 49 | switch (ip.indexToKey(val.toIntern())) { | 49 | switch (ip.indexToKey(val.toIntern())) { |
| 50 | .int_type, | 50 | .int_type, |
| 51 | .ptr_type, | 51 | .ptr_type, |
| 52 | .restricted_ptr_type, | ||
| 52 | .array_type, | 53 | .array_type, |
| 53 | .vector_type, | 54 | .vector_type, |
| 54 | .opt_type, | 55 | .opt_type, |
src/print_zir.zig+8| ... | @@ -622,6 +622,14 @@ const Writer = struct { | ... | @@ -622,6 +622,14 @@ const Writer = struct { |
| 622 | try stream.writeAll(")) "); | 622 | try stream.writeAll(")) "); |
| 623 | try self.writeSrcNode(stream, extra.node); | 623 | try self.writeSrcNode(stream, extra.node); |
| 624 | }, | 624 | }, |
| 625 | .reify_restricted => { | ||
| 626 | const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; | ||
| 627 | const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small); | ||
| 628 | try stream.print("{t}, ", .{name_strat}); | ||
| 629 | try self.writeInstRef(stream, extra.operand); | ||
| 630 | try stream.writeAll(")) "); | ||
| 631 | try self.writeSrcNode(stream, extra.node); | ||
| 632 | }, | ||
| 625 | .reify_fn => { | 633 | .reify_fn => { |
| 626 | const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data; | 634 | const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data; |
| 627 | try self.writeInstRef(stream, extra.param_types); | 635 | try self.writeInstRef(stream, extra.param_types); |