InternPool: fix crashes up to in progress comptime mutation
This commit is contained in:
committed by
Andrew Kelley
parent
1a4626d2cf
commit
72e4ea3821
@@ -730,21 +730,11 @@ pub const Key = union(enum) {
|
||||
|
||||
switch (aggregate.storage) {
|
||||
.bytes => unreachable,
|
||||
.elems => |elems| {
|
||||
var buffer: Key.Int.Storage.BigIntSpace = undefined;
|
||||
for (elems) |elem| std.hash.autoHash(
|
||||
hasher,
|
||||
ip.indexToKey(elem).int.storage.toBigInt(&buffer).to(u8) catch
|
||||
unreachable,
|
||||
);
|
||||
},
|
||||
.elems => |elems| for (elems) |elem| std.hash.autoHash(hasher, elem),
|
||||
.repeated_elem => |elem| {
|
||||
const len = ip.aggregateTypeLen(aggregate.ty);
|
||||
var buffer: Key.Int.Storage.BigIntSpace = undefined;
|
||||
const byte = ip.indexToKey(elem).int.storage.toBigInt(&buffer).to(u8) catch
|
||||
unreachable;
|
||||
var i: u64 = 0;
|
||||
while (i < len) : (i += 1) std.hash.autoHash(hasher, byte);
|
||||
while (i < len) : (i += 1) std.hash.autoHash(hasher, elem);
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -2044,6 +2034,10 @@ pub const Alignment = enum(u6) {
|
||||
assert(n != 0);
|
||||
return fromByteUnits(n);
|
||||
}
|
||||
|
||||
pub fn min(a: Alignment, b: Alignment) Alignment {
|
||||
return @intToEnum(Alignment, @min(@enumToInt(a), @enumToInt(b)));
|
||||
}
|
||||
};
|
||||
|
||||
/// Used for non-sentineled arrays that have length fitting in u32, as well as
|
||||
@@ -3514,16 +3508,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
||||
const ty_key = ip.indexToKey(aggregate.ty);
|
||||
const aggregate_len = ip.aggregateTypeLen(aggregate.ty);
|
||||
switch (aggregate.storage) {
|
||||
.bytes => {
|
||||
.bytes => |bytes| {
|
||||
assert(ty_key.array_type.child == .u8_type);
|
||||
assert(bytes.len == aggregate_len);
|
||||
},
|
||||
.elems => |elems| {
|
||||
assert(elems.len == aggregate_len);
|
||||
for (elems) |elem| assert(elem != .none);
|
||||
},
|
||||
.repeated_elem => |elem| {
|
||||
assert(elem != .none);
|
||||
.repeated_elem => {},
|
||||
}
|
||||
switch (ty_key) {
|
||||
inline .array_type, .vector_type => |seq_type| {
|
||||
for (aggregate.storage.values()) |elem| {
|
||||
assert(ip.typeOf(elem) == seq_type.child);
|
||||
}
|
||||
},
|
||||
.struct_type => |struct_type| {
|
||||
for (
|
||||
aggregate.storage.values(),
|
||||
ip.structPtrUnwrapConst(struct_type.index).?.fields.values(),
|
||||
) |elem, field| {
|
||||
assert(ip.typeOf(elem) == field.ty.toIntern());
|
||||
}
|
||||
},
|
||||
.anon_struct_type => |anon_struct_type| {
|
||||
for (aggregate.storage.values(), anon_struct_type.types) |elem, ty| {
|
||||
assert(ip.typeOf(elem) == ty);
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
if (aggregate_len == 0) {
|
||||
|
||||
140
src/Sema.zig
140
src/Sema.zig
@@ -10252,7 +10252,7 @@ fn zirSwitchCapture(
|
||||
if (try sema.resolveDefinedValue(block, operand_src, operand)) |operand_val| {
|
||||
return sema.addConstant(
|
||||
first_field.ty,
|
||||
operand_val.castTag(.@"union").?.data.val,
|
||||
mod.intern_pool.indexToKey(operand_val.toIntern()).un.val.toValue(),
|
||||
);
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, operand_src, null);
|
||||
@@ -19042,10 +19042,10 @@ fn zirReify(
|
||||
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
|
||||
const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
|
||||
const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime-known");
|
||||
const union_val = val.cast(Value.Payload.Union).?.data;
|
||||
const union_val = mod.intern_pool.indexToKey(val.toIntern()).un;
|
||||
const target = mod.getTarget();
|
||||
const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;
|
||||
if (try union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
|
||||
if (try union_val.val.toValue().anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
|
||||
const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag.toValue(), mod).?;
|
||||
const ip = &mod.intern_pool;
|
||||
switch (@intToEnum(std.builtin.TypeId, tag_index)) {
|
||||
.Type => return Air.Inst.Ref.type_type,
|
||||
@@ -19059,9 +19059,9 @@ fn zirReify(
|
||||
.AnyFrame => return sema.failWithUseOfAsync(block, src),
|
||||
.EnumLiteral => return Air.Inst.Ref.enum_literal_type,
|
||||
.Int => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const signedness_val = try union_val.val.fieldValue(mod, fields.getIndex("signedness").?);
|
||||
const bits_val = try union_val.val.fieldValue(mod, fields.getIndex("bits").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const signedness_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("signedness").?);
|
||||
const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);
|
||||
|
||||
const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
|
||||
const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
|
||||
@@ -19069,9 +19069,9 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Vector => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const len_val = try union_val.val.fieldValue(mod, fields.getIndex("len").?);
|
||||
const child_val = try union_val.val.fieldValue(mod, fields.getIndex("child").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);
|
||||
const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
|
||||
|
||||
const len = @intCast(u32, len_val.toUnsignedInt(mod));
|
||||
const child_ty = child_val.toType();
|
||||
@@ -19085,8 +19085,8 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Float => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const bits_val = try union_val.val.fieldValue(mod, fields.getIndex("bits").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);
|
||||
|
||||
const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
|
||||
const ty = switch (bits) {
|
||||
@@ -19100,15 +19100,15 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Pointer => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const size_val = try union_val.val.fieldValue(mod, fields.getIndex("size").?);
|
||||
const is_const_val = try union_val.val.fieldValue(mod, fields.getIndex("is_const").?);
|
||||
const is_volatile_val = try union_val.val.fieldValue(mod, fields.getIndex("is_volatile").?);
|
||||
const alignment_val = try union_val.val.fieldValue(mod, fields.getIndex("alignment").?);
|
||||
const address_space_val = try union_val.val.fieldValue(mod, fields.getIndex("address_space").?);
|
||||
const child_val = try union_val.val.fieldValue(mod, fields.getIndex("child").?);
|
||||
const is_allowzero_val = try union_val.val.fieldValue(mod, fields.getIndex("is_allowzero").?);
|
||||
const sentinel_val = try union_val.val.fieldValue(mod, fields.getIndex("sentinel").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const size_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("size").?);
|
||||
const is_const_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_const").?);
|
||||
const is_volatile_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_volatile").?);
|
||||
const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);
|
||||
const address_space_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("address_space").?);
|
||||
const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
|
||||
const is_allowzero_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_allowzero").?);
|
||||
const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);
|
||||
|
||||
if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
|
||||
return sema.fail(block, src, "alignment must fit in 'u32'", .{});
|
||||
@@ -19191,10 +19191,10 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Array => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const len_val = try union_val.val.fieldValue(mod, fields.getIndex("len").?);
|
||||
const child_val = try union_val.val.fieldValue(mod, fields.getIndex("child").?);
|
||||
const sentinel_val = try union_val.val.fieldValue(mod, fields.getIndex("sentinel").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);
|
||||
const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
|
||||
const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);
|
||||
|
||||
const len = len_val.toUnsignedInt(mod);
|
||||
const child_ty = child_val.toType();
|
||||
@@ -19210,8 +19210,8 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Optional => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const child_val = try union_val.val.fieldValue(mod, fields.getIndex("child").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
|
||||
|
||||
const child_ty = child_val.toType();
|
||||
|
||||
@@ -19219,9 +19219,9 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.ErrorUnion => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const error_set_val = try union_val.val.fieldValue(mod, fields.getIndex("error_set").?);
|
||||
const payload_val = try union_val.val.fieldValue(mod, fields.getIndex("payload").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const error_set_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("error_set").?);
|
||||
const payload_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("payload").?);
|
||||
|
||||
const error_set_ty = error_set_val.toType();
|
||||
const payload_ty = payload_val.toType();
|
||||
@@ -19234,7 +19234,7 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.ErrorSet => {
|
||||
const payload_val = union_val.val.optionalValue(mod) orelse
|
||||
const payload_val = union_val.val.toValue().optionalValue(mod) orelse
|
||||
return sema.addType(Type.anyerror);
|
||||
|
||||
const len = try sema.usizeCast(block, src, payload_val.sliceLen(mod));
|
||||
@@ -19258,12 +19258,12 @@ fn zirReify(
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Struct => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const layout_val = try union_val.val.fieldValue(mod, fields.getIndex("layout").?);
|
||||
const backing_integer_val = try union_val.val.fieldValue(mod, fields.getIndex("backing_integer").?);
|
||||
const fields_val = try union_val.val.fieldValue(mod, fields.getIndex("fields").?);
|
||||
const decls_val = try union_val.val.fieldValue(mod, fields.getIndex("decls").?);
|
||||
const is_tuple_val = try union_val.val.fieldValue(mod, fields.getIndex("is_tuple").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);
|
||||
const backing_integer_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("backing_integer").?);
|
||||
const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
|
||||
const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
|
||||
const is_tuple_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_tuple").?);
|
||||
|
||||
const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
|
||||
|
||||
@@ -19279,11 +19279,11 @@ fn zirReify(
|
||||
return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
|
||||
},
|
||||
.Enum => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const tag_type_val = try union_val.val.fieldValue(mod, fields.getIndex("tag_type").?);
|
||||
const fields_val = try union_val.val.fieldValue(mod, fields.getIndex("fields").?);
|
||||
const decls_val = try union_val.val.fieldValue(mod, fields.getIndex("decls").?);
|
||||
const is_exhaustive_val = try union_val.val.fieldValue(mod, fields.getIndex("is_exhaustive").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);
|
||||
const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
|
||||
const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
|
||||
const is_exhaustive_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_exhaustive").?);
|
||||
|
||||
// Decls
|
||||
if (decls_val.sliceLen(mod) > 0) {
|
||||
@@ -19318,7 +19318,7 @@ fn zirReify(
|
||||
.nonexhaustive
|
||||
else
|
||||
.explicit,
|
||||
.tag_ty = int_tag_ty.ip_index,
|
||||
.tag_ty = int_tag_ty.toIntern(),
|
||||
});
|
||||
errdefer mod.intern_pool.remove(incomplete_enum.index);
|
||||
|
||||
@@ -19360,7 +19360,7 @@ fn zirReify(
|
||||
return sema.failWithOwnedErrorMsg(msg);
|
||||
}
|
||||
|
||||
if (try incomplete_enum.addFieldValue(&mod.intern_pool, gpa, value_val.ip_index)) |other| {
|
||||
if (try incomplete_enum.addFieldValue(&mod.intern_pool, gpa, value_val.toIntern())) |other| {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});
|
||||
errdefer msg.destroy(gpa);
|
||||
@@ -19375,8 +19375,8 @@ fn zirReify(
|
||||
return sema.analyzeDeclVal(block, src, new_decl_index);
|
||||
},
|
||||
.Opaque => {
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const decls_val = try union_val.val.fieldValue(mod, fields.getIndex("decls").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
|
||||
|
||||
// Decls
|
||||
if (decls_val.sliceLen(mod) > 0) {
|
||||
@@ -19419,11 +19419,11 @@ fn zirReify(
|
||||
return sema.analyzeDeclVal(block, src, new_decl_index);
|
||||
},
|
||||
.Union => {
|
||||
const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);
|
||||
const layout_val = try union_val.val.fieldValue(mod, fields.getIndex("layout").?);
|
||||
const tag_type_val = try union_val.val.fieldValue(mod, fields.getIndex("tag_type").?);
|
||||
const fields_val = try union_val.val.fieldValue(mod, fields.getIndex("fields").?);
|
||||
const decls_val = try union_val.val.fieldValue(mod, fields.getIndex("decls").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);
|
||||
const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);
|
||||
const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
|
||||
const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
|
||||
|
||||
// Decls
|
||||
if (decls_val.sliceLen(mod) > 0) {
|
||||
@@ -19491,7 +19491,7 @@ fn zirReify(
|
||||
if (tag_type_val.optionalValue(mod)) |payload_val| {
|
||||
union_obj.tag_ty = payload_val.toType();
|
||||
|
||||
const enum_type = switch (mod.intern_pool.indexToKey(union_obj.tag_ty.ip_index)) {
|
||||
const enum_type = switch (mod.intern_pool.indexToKey(union_obj.tag_ty.toIntern())) {
|
||||
.enum_type => |x| x,
|
||||
else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}),
|
||||
};
|
||||
@@ -19620,13 +19620,13 @@ fn zirReify(
|
||||
return sema.analyzeDeclVal(block, src, new_decl_index);
|
||||
},
|
||||
.Fn => {
|
||||
const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);
|
||||
const calling_convention_val = try union_val.val.fieldValue(mod, fields.getIndex("calling_convention").?);
|
||||
const alignment_val = try union_val.val.fieldValue(mod, fields.getIndex("alignment").?);
|
||||
const is_generic_val = try union_val.val.fieldValue(mod, fields.getIndex("is_generic").?);
|
||||
const is_var_args_val = try union_val.val.fieldValue(mod, fields.getIndex("is_var_args").?);
|
||||
const return_type_val = try union_val.val.fieldValue(mod, fields.getIndex("return_type").?);
|
||||
const params_val = try union_val.val.fieldValue(mod, fields.getIndex("params").?);
|
||||
const fields = ip.typeOf(union_val.val).toType().structFields(mod);
|
||||
const calling_convention_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("calling_convention").?);
|
||||
const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);
|
||||
const is_generic_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_generic").?);
|
||||
const is_var_args_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_var_args").?);
|
||||
const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("return_type").?);
|
||||
const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("params").?);
|
||||
|
||||
const is_generic = is_generic_val.toBool(mod);
|
||||
if (is_generic) {
|
||||
@@ -25204,12 +25204,12 @@ fn unionFieldPtr(
|
||||
if (union_val.isUndef(mod)) {
|
||||
return sema.failWithUseOfUndef(block, src);
|
||||
}
|
||||
const tag_and_val = union_val.castTag(.@"union").?.data;
|
||||
const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;
|
||||
const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
|
||||
const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
|
||||
const tag_matches = un.tag == field_tag.toIntern();
|
||||
if (!tag_matches) {
|
||||
const msg = msg: {
|
||||
const active_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, mod).?;
|
||||
const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
|
||||
const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
|
||||
const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
@@ -25269,16 +25269,16 @@ fn unionFieldVal(
|
||||
if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {
|
||||
if (union_val.isUndef(mod)) return sema.addConstUndef(field.ty);
|
||||
|
||||
const tag_and_val = union_val.castTag(.@"union").?.data;
|
||||
const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;
|
||||
const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
|
||||
const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);
|
||||
const tag_matches = un.tag == field_tag.toIntern();
|
||||
switch (union_obj.layout) {
|
||||
.Auto => {
|
||||
if (tag_matches) {
|
||||
return sema.addConstant(field.ty, tag_and_val.val);
|
||||
return sema.addConstant(field.ty, un.val.toValue());
|
||||
} else {
|
||||
const msg = msg: {
|
||||
const active_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, mod).?;
|
||||
const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
|
||||
const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
|
||||
const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
@@ -25290,10 +25290,10 @@ fn unionFieldVal(
|
||||
},
|
||||
.Packed, .Extern => {
|
||||
if (tag_matches) {
|
||||
return sema.addConstant(field.ty, tag_and_val.val);
|
||||
return sema.addConstant(field.ty, un.val.toValue());
|
||||
} else {
|
||||
const old_ty = union_ty.unionFieldType(tag_and_val.tag, mod);
|
||||
if (try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0)) |new_val| {
|
||||
const old_ty = union_ty.unionFieldType(un.tag.toValue(), mod);
|
||||
if (try sema.bitCastVal(block, src, un.val.toValue(), old_ty, field.ty, 0)) |new_val| {
|
||||
return sema.addConstant(field.ty, new_val);
|
||||
}
|
||||
}
|
||||
@@ -27626,7 +27626,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
|
||||
// allocations is relevant to this function, or why it would have
|
||||
// different behavior depending on whether the types were inferred.
|
||||
// Something seems wrong here.
|
||||
switch (prev_ptr_ty.ip_index) {
|
||||
switch (prev_ptr_ty.toIntern()) {
|
||||
.inferred_alloc_mut_type, .inferred_alloc_const_type => return null,
|
||||
else => {},
|
||||
}
|
||||
|
||||
@@ -3208,7 +3208,8 @@ pub const DeclGen = struct {
|
||||
return llvm_type.getUndef();
|
||||
}
|
||||
|
||||
switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {
|
||||
const val_key = mod.intern_pool.indexToKey(tv.val.toIntern());
|
||||
switch (val_key) {
|
||||
.int_type,
|
||||
.ptr_type,
|
||||
.array_type,
|
||||
@@ -3242,10 +3243,18 @@ pub const DeclGen = struct {
|
||||
},
|
||||
},
|
||||
.variable,
|
||||
.extern_func,
|
||||
.func,
|
||||
.enum_literal,
|
||||
=> unreachable, // non-runtime values
|
||||
.extern_func, .func => {
|
||||
const fn_decl_index = switch (val_key) {
|
||||
.extern_func => |extern_func| extern_func.decl,
|
||||
.func => |func| mod.funcPtr(func.index).owner_decl,
|
||||
else => unreachable,
|
||||
};
|
||||
const fn_decl = dg.module.declPtr(fn_decl_index);
|
||||
dg.module.markDeclAlive(fn_decl);
|
||||
return dg.resolveLlvmFunction(fn_decl_index);
|
||||
},
|
||||
.int => |int| {
|
||||
var bigint_space: Value.BigIntSpace = undefined;
|
||||
const bigint = int.storage.toBigInt(&bigint_space);
|
||||
|
||||
@@ -1961,12 +1961,31 @@ pub const Value = struct {
|
||||
mod: *Module,
|
||||
) Allocator.Error!Value {
|
||||
const elem_ty = ty.elemType2(mod);
|
||||
const ptr_ty_key = mod.intern_pool.indexToKey(ty.toIntern()).ptr_type;
|
||||
assert(ptr_ty_key.host_size == 0);
|
||||
assert(ptr_ty_key.bit_offset == 0);
|
||||
assert(ptr_ty_key.vector_index == .none);
|
||||
const elem_alignment = InternPool.Alignment.fromByteUnits(elem_ty.abiAlignment(mod));
|
||||
const alignment = switch (ptr_ty_key.alignment) {
|
||||
.none => .none,
|
||||
else => ptr_ty_key.alignment.min(
|
||||
@intToEnum(InternPool.Alignment, @ctz(index * elem_ty.abiSize(mod))),
|
||||
),
|
||||
};
|
||||
const ptr_ty = try mod.ptrType(.{
|
||||
.elem_type = elem_ty.toIntern(),
|
||||
.alignment = if (alignment == elem_alignment) .none else alignment,
|
||||
.is_const = ptr_ty_key.is_const,
|
||||
.is_volatile = ptr_ty_key.is_volatile,
|
||||
.is_allowzero = ptr_ty_key.is_allowzero,
|
||||
.address_space = ptr_ty_key.address_space,
|
||||
});
|
||||
const ptr_val = switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
.ptr => |ptr| ptr: {
|
||||
switch (ptr.addr) {
|
||||
.elem => |elem| if (mod.intern_pool.typeOf(elem.base).toType().elemType2(mod).eql(elem_ty, mod))
|
||||
return (try mod.intern(.{ .ptr = .{
|
||||
.ty = ty.toIntern(),
|
||||
.ty = ptr_ty.toIntern(),
|
||||
.addr = .{ .elem = .{
|
||||
.base = elem.base,
|
||||
.index = elem.index + index,
|
||||
@@ -1982,7 +2001,7 @@ pub const Value = struct {
|
||||
else => val,
|
||||
};
|
||||
return (try mod.intern(.{ .ptr = .{
|
||||
.ty = ty.toIntern(),
|
||||
.ty = ptr_ty.toIntern(),
|
||||
.addr = .{ .elem = .{
|
||||
.base = ptr_val.toIntern(),
|
||||
.index = index,
|
||||
|
||||
Reference in New Issue
Block a user