| author | |
| committer | |
| log | 4fe0c583be8890b1cb8059c2daff3bd82c53d2e9 |
| tree | e491e68236f5c090076459d63d475dce93aa0d84 |
| parent | 4d88f825bc5eb14aa00446f046ab4714a4fdce70 |
4 files changed, 57 insertions(+), 24 deletions(-)
src/Module.zig+1| ... | ... | @@ -6716,6 +6716,7 @@ fn reportRetryableFileError( |
| 6716 | 6716 | } |
| 6717 | 6717 | |
| 6718 | 6718 | pub fn markReferencedDeclsAlive(mod: *Module, val: Value) void { |
| 6719 | if (val.ip_index != .none) return; | |
| 6719 | 6720 | switch (val.tag()) { |
| 6720 | 6721 | .decl_ref_mut => return mod.markDeclIndexAlive(val.castTag(.decl_ref_mut).?.data.decl_index), |
| 6721 | 6722 | .extern_fn => return mod.markDeclIndexAlive(val.castTag(.extern_fn).?.data.owner_decl), |
src/Sema.zig+14-6| ... | ... | @@ -12307,8 +12307,7 @@ fn zirShl( |
| 12307 | 12307 | if (block.wantSafety()) { |
| 12308 | 12308 | const bit_count = scalar_ty.intInfo(mod).bits; |
| 12309 | 12309 | if (!std.math.isPowerOfTwo(bit_count)) { |
| 12310 | const bit_count_val = try mod.intValue(scalar_ty, bit_count); | |
| 12311 | ||
| 12310 | const bit_count_val = try mod.intValue(scalar_rhs_ty, bit_count); | |
| 12312 | 12311 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { |
| 12313 | 12312 | const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val)); |
| 12314 | 12313 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt); |
| ... | ... | @@ -27391,10 +27390,19 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { |
| 27391 | 27390 | const prev_ptr = while (air_tags[ptr_inst] == .bitcast) { |
| 27392 | 27391 | const prev_ptr = air_datas[ptr_inst].ty_op.operand; |
| 27393 | 27392 | const prev_ptr_ty = sema.typeOf(prev_ptr); |
| 27394 | const prev_ptr_child_ty = switch (prev_ptr_ty.tag()) { | |
| 27395 | .pointer => prev_ptr_ty.castTag(.pointer).?.data.pointee_type, | |
| 27396 | else => return null, | |
| 27397 | }; | |
| 27393 | if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null; | |
| 27394 | ||
| 27395 | // TODO: I noticed that the behavior tests do not pass if these two | |
| 27396 | // checks are missing. I don't understand why the presence of inferred | |
| 27397 | // allocations is relevant to this function, or why it would have | |
| 27398 | // different behavior depending on whether the types were inferred. | |
| 27399 | // Something seems wrong here. | |
| 27400 | if (prev_ptr_ty.ip_index == .none) { | |
| 27401 | if (prev_ptr_ty.tag() == .inferred_alloc_mut) return null; | |
| 27402 | if (prev_ptr_ty.tag() == .inferred_alloc_const) return null; | |
| 27403 | } | |
| 27404 | ||
| 27405 | const prev_ptr_child_ty = prev_ptr_ty.childType(mod); | |
| 27398 | 27406 | if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr; |
| 27399 | 27407 | ptr_inst = Air.refToIndex(prev_ptr) orelse return null; |
| 27400 | 27408 | } else return null; |
src/type.zig+15-8| ... | ... | @@ -2058,16 +2058,23 @@ pub const Type = struct { |
| 2058 | 2058 | } |
| 2059 | 2059 | } |
| 2060 | 2060 | |
| 2061 | pub fn ptrAddressSpace(self: Type, mod: *const Module) std.builtin.AddressSpace { | |
| 2062 | return switch (self.tag()) { | |
| 2063 | .pointer => self.castTag(.pointer).?.data.@"addrspace", | |
| 2061 | pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { | |
| 2062 | return switch (ty.ip_index) { | |
| 2063 | .none => switch (ty.tag()) { | |
| 2064 | .pointer => ty.castTag(.pointer).?.data.@"addrspace", | |
| 2064 | 2065 | |
| 2065 | .optional => { | |
| 2066 | const child_type = self.optionalChild(mod); | |
| 2067 | return child_type.ptrAddressSpace(mod); | |
| 2068 | }, | |
| 2066 | .optional => { | |
| 2067 | const child_type = ty.optionalChild(mod); | |
| 2068 | return child_type.ptrAddressSpace(mod); | |
| 2069 | }, | |
| 2069 | 2070 | |
| 2070 | else => unreachable, | |
| 2071 | else => unreachable, | |
| 2072 | }, | |
| 2073 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2074 | .ptr_type => |ptr_type| ptr_type.address_space, | |
| 2075 | .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space, | |
| 2076 | else => unreachable, | |
| 2077 | }, | |
| 2071 | 2078 | }; |
| 2072 | 2079 | } |
| 2073 | 2080 |
src/value.zig+27-10| ... | ... | @@ -644,15 +644,32 @@ pub const Value = struct { |
| 644 | 644 | |
| 645 | 645 | /// Asserts the type is an enum type. |
| 646 | 646 | pub fn toEnum(val: Value, comptime E: type) E { |
| 647 | switch (val.tag()) { | |
| 648 | .enum_field_index => { | |
| 649 | const field_index = val.castTag(.enum_field_index).?.data; | |
| 650 | return @intToEnum(E, field_index); | |
| 647 | switch (val.ip_index) { | |
| 648 | .calling_convention_c => { | |
| 649 | if (E == std.builtin.CallingConvention) { | |
| 650 | return .C; | |
| 651 | } else { | |
| 652 | unreachable; | |
| 653 | } | |
| 654 | }, | |
| 655 | .calling_convention_inline => { | |
| 656 | if (E == std.builtin.CallingConvention) { | |
| 657 | return .Inline; | |
| 658 | } else { | |
| 659 | unreachable; | |
| 660 | } | |
| 651 | 661 | }, |
| 652 | .the_only_possible_value => { | |
| 653 | const fields = std.meta.fields(E); | |
| 654 | assert(fields.len == 1); | |
| 655 | return @intToEnum(E, fields[0].value); | |
| 662 | .none => switch (val.tag()) { | |
| 663 | .enum_field_index => { | |
| 664 | const field_index = val.castTag(.enum_field_index).?.data; | |
| 665 | return @intToEnum(E, field_index); | |
| 666 | }, | |
| 667 | .the_only_possible_value => { | |
| 668 | const fields = std.meta.fields(E); | |
| 669 | assert(fields.len == 1); | |
| 670 | return @intToEnum(E, fields[0].value); | |
| 671 | }, | |
| 672 | else => unreachable, | |
| 656 | 673 | }, |
| 657 | 674 | else => unreachable, |
| 658 | 675 | } |
| ... | ... | @@ -2177,7 +2194,7 @@ pub const Value = struct { |
| 2177 | 2194 | std.hash.autoHash(hasher, zig_ty_tag); |
| 2178 | 2195 | if (val.isUndef()) return; |
| 2179 | 2196 | // The value is runtime-known and shouldn't affect the hash. |
| 2180 | if (val.tag() == .runtime_value) return; | |
| 2197 | if (val.isRuntimeValue()) return; | |
| 2181 | 2198 | |
| 2182 | 2199 | switch (zig_ty_tag) { |
| 2183 | 2200 | .Opaque => unreachable, // Cannot hash opaque types |
| ... | ... | @@ -2323,7 +2340,7 @@ pub const Value = struct { |
| 2323 | 2340 | pub fn hashUncoerced(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void { |
| 2324 | 2341 | if (val.isUndef()) return; |
| 2325 | 2342 | // The value is runtime-known and shouldn't affect the hash. |
| 2326 | if (val.tag() == .runtime_value) return; | |
| 2343 | if (val.isRuntimeValue()) return; | |
| 2327 | 2344 | |
| 2328 | 2345 | switch (ty.zigTypeTag(mod)) { |
| 2329 | 2346 | .Opaque => unreachable, // Cannot hash opaque types |