mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 17:35:12 +00:00
Merge pull request #11185 from topolarity/bugfix-11159
stage2: resolve panic on array-like tuple initialization
This commit is contained in:
commit
1149e8bb08
@ -4092,15 +4092,17 @@ fn structDeclInner(
|
||||
const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
|
||||
wip_members.appendToField(doc_comment_index);
|
||||
|
||||
known_non_opv = known_non_opv or
|
||||
nodeImpliesMoreThanOnePossibleValue(tree, member.ast.type_expr);
|
||||
known_comptime_only = known_comptime_only or
|
||||
nodeImpliesComptimeOnly(tree, member.ast.type_expr);
|
||||
|
||||
const have_align = member.ast.align_expr != 0;
|
||||
const have_value = member.ast.value_expr != 0;
|
||||
const is_comptime = member.comptime_token != null;
|
||||
const unused = false;
|
||||
|
||||
if (!is_comptime) {
|
||||
known_non_opv = known_non_opv or
|
||||
nodeImpliesMoreThanOnePossibleValue(tree, member.ast.type_expr);
|
||||
known_comptime_only = known_comptime_only or
|
||||
nodeImpliesComptimeOnly(tree, member.ast.type_expr);
|
||||
}
|
||||
wip_members.nextField(bits_per_field, .{ have_align, have_value, is_comptime, unused });
|
||||
|
||||
if (have_align) {
|
||||
|
||||
13
src/Sema.zig
13
src/Sema.zig
@ -3203,11 +3203,6 @@ fn zirValidateArrayInit(
|
||||
|
||||
// Determine whether the value stored to this pointer is comptime-known.
|
||||
|
||||
if (opt_opv) |opv| {
|
||||
element_vals[i] = opv;
|
||||
continue;
|
||||
}
|
||||
|
||||
const elem_ptr_air_ref = sema.inst_map.get(elem_ptr).?;
|
||||
const elem_ptr_air_inst = Air.refToIndex(elem_ptr_air_ref).?;
|
||||
// Find the block index of the elem_ptr so that we can look at the next
|
||||
@ -3223,6 +3218,12 @@ fn zirValidateArrayInit(
|
||||
break :inst block.instructions.items[block_index + 1];
|
||||
};
|
||||
|
||||
// Array has one possible value, so value is always comptime-known
|
||||
if (opt_opv) |opv| {
|
||||
element_vals[i] = opv;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the next instructon is a store with a comptime operand, this element
|
||||
// is comptime.
|
||||
switch (air_tags[next_air_inst]) {
|
||||
@ -20860,6 +20861,7 @@ pub fn typeHasOnePossibleValue(
|
||||
const resolved_ty = try sema.resolveTypeFields(block, src, ty);
|
||||
const s = resolved_ty.castTag(.@"struct").?.data;
|
||||
for (s.fields.values()) |value| {
|
||||
if (value.is_comptime) continue;
|
||||
if ((try sema.typeHasOnePossibleValue(block, src, value.ty)) == null) {
|
||||
return null;
|
||||
}
|
||||
@ -21532,6 +21534,7 @@ fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) C
|
||||
|
||||
struct_obj.requires_comptime = .wip;
|
||||
for (struct_obj.fields.values()) |field| {
|
||||
if (field.is_comptime) continue;
|
||||
if (try sema.typeRequiresComptime(block, src, field.ty)) {
|
||||
struct_obj.requires_comptime = .yes;
|
||||
return true;
|
||||
|
||||
@ -5422,21 +5422,22 @@ pub const FuncGen = struct {
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
const dest_ptr = try self.resolveInst(bin_op.lhs);
|
||||
const ptr_ty = self.air.typeOf(bin_op.lhs);
|
||||
const operand_ty = ptr_ty.childType();
|
||||
if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;
|
||||
|
||||
// TODO Sema should emit a different instruction when the store should
|
||||
// possibly do the safety 0xaa bytes for undefined.
|
||||
const val_is_undef = if (self.air.value(bin_op.rhs)) |val| val.isUndefDeep() else false;
|
||||
if (val_is_undef) {
|
||||
const elem_ty = ptr_ty.childType();
|
||||
const target = self.dg.module.getTarget();
|
||||
const elem_size = elem_ty.abiSize(target);
|
||||
const operand_size = operand_ty.abiSize(target);
|
||||
const u8_llvm_ty = self.context.intType(8);
|
||||
const ptr_u8_llvm_ty = u8_llvm_ty.pointerType(0);
|
||||
const dest_ptr_u8 = self.builder.buildBitCast(dest_ptr, ptr_u8_llvm_ty, "");
|
||||
const fill_char = u8_llvm_ty.constInt(0xaa, .False);
|
||||
const dest_ptr_align = ptr_ty.ptrAlignment(target);
|
||||
const usize_llvm_ty = try self.dg.llvmType(Type.usize);
|
||||
const len = usize_llvm_ty.constInt(elem_size, .False);
|
||||
const len = usize_llvm_ty.constInt(operand_size, .False);
|
||||
_ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
|
||||
if (self.dg.module.comp.bin_file.options.valgrind) {
|
||||
// TODO generate valgrind client request to mark byte range as undefined
|
||||
|
||||
@ -2098,6 +2098,7 @@ pub const Type = extern union {
|
||||
}
|
||||
assert(struct_obj.haveFieldTypes());
|
||||
for (struct_obj.fields.values()) |value| {
|
||||
if (value.is_comptime) continue;
|
||||
if (value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only))
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@ -65,8 +65,11 @@ test {
|
||||
_ = @import("behavior/bugs/10970.zig");
|
||||
_ = @import("behavior/bugs/11046.zig");
|
||||
_ = @import("behavior/bugs/11139.zig");
|
||||
_ = @import("behavior/bugs/11159.zig");
|
||||
_ = @import("behavior/bugs/11162.zig");
|
||||
_ = @import("behavior/bugs/11165.zig");
|
||||
_ = @import("behavior/bugs/11181.zig");
|
||||
_ = @import("behavior/bugs/11182.zig");
|
||||
_ = @import("behavior/call.zig");
|
||||
_ = @import("behavior/cast.zig");
|
||||
_ = @import("behavior/comptime_memory.zig");
|
||||
|
||||
23
test/behavior/bugs/11159.zig
Normal file
23
test/behavior/bugs/11159.zig
Normal file
@ -0,0 +1,23 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
test {
|
||||
const T = @TypeOf(.{ @as(i32, 0), @as(u32, 0) });
|
||||
var a: T = .{ 0, 0 };
|
||||
_ = a;
|
||||
}
|
||||
|
||||
test {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
comptime x: i32 = 0,
|
||||
comptime y: u32 = 0,
|
||||
};
|
||||
var a: S = .{};
|
||||
_ = a;
|
||||
var b = S{};
|
||||
_ = b;
|
||||
}
|
||||
16
test/behavior/bugs/11162.zig
Normal file
16
test/behavior/bugs/11162.zig
Normal file
@ -0,0 +1,16 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const expect = std.testing.expect;
|
||||
|
||||
test {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
var x: u32 = 15;
|
||||
const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x });
|
||||
var a: T = .{ -1234, 5678, x + 1 };
|
||||
|
||||
try expect(a[0] == -1234);
|
||||
try expect(a[1] == 5678);
|
||||
try expect(a[2] == 16);
|
||||
}
|
||||
10
test/behavior/bugs/11182.zig
Normal file
10
test/behavior/bugs/11182.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
test {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
const T = @TypeOf(.{ @as(i32, 0), @as(u32, 0) });
|
||||
var a = T{ 0, 0 };
|
||||
_ = a;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user