mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-09 23:29:03 +00:00
stage2: more InternPool-related fixes
This commit is contained in:
parent
4d88f825bc
commit
4fe0c583be
4 changed files with 57 additions and 24 deletions
|
|
@ -6716,6 +6716,7 @@ fn reportRetryableFileError(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn markReferencedDeclsAlive(mod: *Module, val: Value) void {
|
pub fn markReferencedDeclsAlive(mod: *Module, val: Value) void {
|
||||||
|
if (val.ip_index != .none) return;
|
||||||
switch (val.tag()) {
|
switch (val.tag()) {
|
||||||
.decl_ref_mut => return mod.markDeclIndexAlive(val.castTag(.decl_ref_mut).?.data.decl_index),
|
.decl_ref_mut => return mod.markDeclIndexAlive(val.castTag(.decl_ref_mut).?.data.decl_index),
|
||||||
.extern_fn => return mod.markDeclIndexAlive(val.castTag(.extern_fn).?.data.owner_decl),
|
.extern_fn => return mod.markDeclIndexAlive(val.castTag(.extern_fn).?.data.owner_decl),
|
||||||
|
|
|
||||||
20
src/Sema.zig
20
src/Sema.zig
|
|
@ -12307,8 +12307,7 @@ fn zirShl(
|
||||||
if (block.wantSafety()) {
|
if (block.wantSafety()) {
|
||||||
const bit_count = scalar_ty.intInfo(mod).bits;
|
const bit_count = scalar_ty.intInfo(mod).bits;
|
||||||
if (!std.math.isPowerOfTwo(bit_count)) {
|
if (!std.math.isPowerOfTwo(bit_count)) {
|
||||||
const bit_count_val = try mod.intValue(scalar_ty, bit_count);
|
const bit_count_val = try mod.intValue(scalar_rhs_ty, bit_count);
|
||||||
|
|
||||||
const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
|
const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
|
||||||
const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
|
const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
|
||||||
const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
|
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 {
|
||||||
const prev_ptr = while (air_tags[ptr_inst] == .bitcast) {
|
const prev_ptr = while (air_tags[ptr_inst] == .bitcast) {
|
||||||
const prev_ptr = air_datas[ptr_inst].ty_op.operand;
|
const prev_ptr = air_datas[ptr_inst].ty_op.operand;
|
||||||
const prev_ptr_ty = sema.typeOf(prev_ptr);
|
const prev_ptr_ty = sema.typeOf(prev_ptr);
|
||||||
const prev_ptr_child_ty = switch (prev_ptr_ty.tag()) {
|
if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null;
|
||||||
.pointer => prev_ptr_ty.castTag(.pointer).?.data.pointee_type,
|
|
||||||
else => return null,
|
// TODO: I noticed that the behavior tests do not pass if these two
|
||||||
};
|
// checks are missing. I don't understand why the presence of inferred
|
||||||
|
// allocations is relevant to this function, or why it would have
|
||||||
|
// different behavior depending on whether the types were inferred.
|
||||||
|
// Something seems wrong here.
|
||||||
|
if (prev_ptr_ty.ip_index == .none) {
|
||||||
|
if (prev_ptr_ty.tag() == .inferred_alloc_mut) return null;
|
||||||
|
if (prev_ptr_ty.tag() == .inferred_alloc_const) return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const prev_ptr_child_ty = prev_ptr_ty.childType(mod);
|
||||||
if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;
|
if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;
|
||||||
ptr_inst = Air.refToIndex(prev_ptr) orelse return null;
|
ptr_inst = Air.refToIndex(prev_ptr) orelse return null;
|
||||||
} else return null;
|
} else return null;
|
||||||
|
|
|
||||||
23
src/type.zig
23
src/type.zig
|
|
@ -2058,16 +2058,23 @@ pub const Type = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ptrAddressSpace(self: Type, mod: *const Module) std.builtin.AddressSpace {
|
pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace {
|
||||||
return switch (self.tag()) {
|
return switch (ty.ip_index) {
|
||||||
.pointer => self.castTag(.pointer).?.data.@"addrspace",
|
.none => switch (ty.tag()) {
|
||||||
|
.pointer => ty.castTag(.pointer).?.data.@"addrspace",
|
||||||
|
|
||||||
.optional => {
|
.optional => {
|
||||||
const child_type = self.optionalChild(mod);
|
const child_type = ty.optionalChild(mod);
|
||||||
return child_type.ptrAddressSpace(mod);
|
return child_type.ptrAddressSpace(mod);
|
||||||
|
},
|
||||||
|
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||||
|
.ptr_type => |ptr_type| ptr_type.address_space,
|
||||||
|
.opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space,
|
||||||
|
else => unreachable,
|
||||||
},
|
},
|
||||||
|
|
||||||
else => unreachable,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -644,15 +644,32 @@ pub const Value = struct {
|
||||||
|
|
||||||
/// Asserts the type is an enum type.
|
/// Asserts the type is an enum type.
|
||||||
pub fn toEnum(val: Value, comptime E: type) E {
|
pub fn toEnum(val: Value, comptime E: type) E {
|
||||||
switch (val.tag()) {
|
switch (val.ip_index) {
|
||||||
.enum_field_index => {
|
.calling_convention_c => {
|
||||||
const field_index = val.castTag(.enum_field_index).?.data;
|
if (E == std.builtin.CallingConvention) {
|
||||||
return @intToEnum(E, field_index);
|
return .C;
|
||||||
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.the_only_possible_value => {
|
.calling_convention_inline => {
|
||||||
const fields = std.meta.fields(E);
|
if (E == std.builtin.CallingConvention) {
|
||||||
assert(fields.len == 1);
|
return .Inline;
|
||||||
return @intToEnum(E, fields[0].value);
|
} else {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.none => switch (val.tag()) {
|
||||||
|
.enum_field_index => {
|
||||||
|
const field_index = val.castTag(.enum_field_index).?.data;
|
||||||
|
return @intToEnum(E, field_index);
|
||||||
|
},
|
||||||
|
.the_only_possible_value => {
|
||||||
|
const fields = std.meta.fields(E);
|
||||||
|
assert(fields.len == 1);
|
||||||
|
return @intToEnum(E, fields[0].value);
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
|
|
@ -2177,7 +2194,7 @@ pub const Value = struct {
|
||||||
std.hash.autoHash(hasher, zig_ty_tag);
|
std.hash.autoHash(hasher, zig_ty_tag);
|
||||||
if (val.isUndef()) return;
|
if (val.isUndef()) return;
|
||||||
// The value is runtime-known and shouldn't affect the hash.
|
// The value is runtime-known and shouldn't affect the hash.
|
||||||
if (val.tag() == .runtime_value) return;
|
if (val.isRuntimeValue()) return;
|
||||||
|
|
||||||
switch (zig_ty_tag) {
|
switch (zig_ty_tag) {
|
||||||
.Opaque => unreachable, // Cannot hash opaque types
|
.Opaque => unreachable, // Cannot hash opaque types
|
||||||
|
|
@ -2323,7 +2340,7 @@ pub const Value = struct {
|
||||||
pub fn hashUncoerced(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
|
pub fn hashUncoerced(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
|
||||||
if (val.isUndef()) return;
|
if (val.isUndef()) return;
|
||||||
// The value is runtime-known and shouldn't affect the hash.
|
// The value is runtime-known and shouldn't affect the hash.
|
||||||
if (val.tag() == .runtime_value) return;
|
if (val.isRuntimeValue()) return;
|
||||||
|
|
||||||
switch (ty.zigTypeTag(mod)) {
|
switch (ty.zigTypeTag(mod)) {
|
||||||
.Opaque => unreachable, // Cannot hash opaque types
|
.Opaque => unreachable, // Cannot hash opaque types
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue