astgen: enable array_list.zig corpus test
Fix multiple bugs found via the array_list.zig corpus test: - Fix anytype param ref/index double-conversion (addStrTok returns a ref, don't add ZIR_REF_START_INDEX again) - Implement is_generic param tracking via is_used_or_discarded pointer in ScopeLocalVal - Fix globalVarDecl declaration src_line: use type_gz.decl_line instead of ag->source_line (which was advanced by init expression) - Fix cppcheck warning: remove redundant (0u << 2) in bitmask - Implement fetchRemoveRefEntries and ret_param_refs in addFunc - Add func_fancy case to buildHashSkipMask in test - Fix valgrind: zero elem_val_imm padding, skip addNodeExtended undefined small field, handle more padding-sensitive tags Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -81,6 +81,40 @@ fn buildHashSkipMask(gpa: Allocator, ref: Zir) ![]bool {
|
||||
}
|
||||
}
|
||||
},
|
||||
.func_fancy => {
|
||||
// FuncFancy: param_block(1) + body_len(1) + bits(1)
|
||||
// + trailing cc + ret_ty + noalias + body + SrcLocs(3) + proto_hash(4).
|
||||
const pi = ref_datas[i].pl_node.payload_index;
|
||||
const body_len: u32 = ref.extra[pi + 1];
|
||||
const bits: u32 = ref.extra[pi + 2];
|
||||
var ei: u32 = pi + 3;
|
||||
const has_cc_ref: bool = (bits & (1 << 3)) != 0;
|
||||
const has_cc_body: bool = (bits & (1 << 4)) != 0;
|
||||
const has_ret_ty_ref: bool = (bits & (1 << 5)) != 0;
|
||||
const has_ret_ty_body: bool = (bits & (1 << 6)) != 0;
|
||||
const has_any_noalias: bool = (bits & (1 << 7)) != 0;
|
||||
if (has_cc_body) {
|
||||
const cc_body_len = ref.extra[ei];
|
||||
ei += 1 + cc_body_len;
|
||||
} else if (has_cc_ref) {
|
||||
ei += 1;
|
||||
}
|
||||
if (has_ret_ty_body) {
|
||||
const ret_body_len = ref.extra[ei];
|
||||
ei += 1 + ret_body_len;
|
||||
} else if (has_ret_ty_ref) {
|
||||
ei += 1;
|
||||
}
|
||||
if (has_any_noalias) ei += 1;
|
||||
// body + SrcLocs(3) + proto_hash(4)
|
||||
if (body_len > 0) {
|
||||
const hash_start = ei + body_len + 3;
|
||||
for (0..4) |j| {
|
||||
if (hash_start + j < ref_extra_len)
|
||||
skip[hash_start + j] = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
@@ -300,7 +334,35 @@ fn expectEqualZir(gpa: Allocator, ref: Zir, got: c.Zir) !void {
|
||||
|
||||
// 3. Compare instruction data field-by-field.
|
||||
for (0..ref_len) |i| {
|
||||
try expectEqualData(i, ref_tags[i], ref_datas[i], got.inst_datas[i]);
|
||||
expectEqualData(i, ref_tags[i], ref_datas[i], got.inst_datas[i]) catch {
|
||||
// Print nearest declaration for context.
|
||||
var j: usize = i;
|
||||
while (j > 0) {
|
||||
j -= 1;
|
||||
if (ref_tags[j] == .declaration) {
|
||||
std.debug.print(" nearest decl at [{d}]: src_node={d}\n", .{
|
||||
j, ref_datas[j].declaration.src_node,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Print what tags are at the operand positions if break_inline.
|
||||
if (ref_tags[i] == .break_inline) {
|
||||
const r_op = @intFromEnum(ref_datas[i].@"break".operand);
|
||||
const g_op = got.inst_datas[i].break_data.operand;
|
||||
if (r_op >= 124 and r_op - 124 < ref_len) {
|
||||
std.debug.print(" ref operand inst[{d}] tag={d}\n", .{
|
||||
r_op - 124, @intFromEnum(ref_tags[r_op - 124]),
|
||||
});
|
||||
}
|
||||
if (g_op >= 124 and g_op - 124 < ref_len) {
|
||||
std.debug.print(" got operand inst[{d}] tag={d}\n", .{
|
||||
g_op - 124, @intFromEnum(ref_tags[g_op - 124]),
|
||||
});
|
||||
}
|
||||
}
|
||||
return error.TestExpectedEqual;
|
||||
};
|
||||
}
|
||||
// 4. Compare string bytes.
|
||||
const ref_sb_len: u32 = @intCast(ref.string_bytes.len);
|
||||
@@ -370,6 +432,17 @@ fn expectEqualData(
|
||||
.enum_decl,
|
||||
.union_decl,
|
||||
.opaque_decl,
|
||||
// addNodeExtended sets small = undefined (AstGen.zig:12775).
|
||||
.this,
|
||||
.ret_addr,
|
||||
.error_return_trace,
|
||||
.frame,
|
||||
.frame_address,
|
||||
.breakpoint,
|
||||
.disable_instrumentation,
|
||||
.disable_intrinsics,
|
||||
.in_comptime,
|
||||
.c_va_start,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
@@ -522,6 +595,7 @@ fn expectEqualData(
|
||||
},
|
||||
.func,
|
||||
.func_inferred,
|
||||
.func_fancy,
|
||||
.array_type,
|
||||
.array_type_sentinel,
|
||||
.array_cat,
|
||||
@@ -678,6 +752,10 @@ fn expectEqualData(
|
||||
.@"unreachable",
|
||||
// .save_err_ret_index data format (operand only):
|
||||
.save_err_ret_index,
|
||||
// .float data format (f32 = 4 bytes, second word is padding):
|
||||
.float,
|
||||
// .elem_val_imm data format (u32 + u8, 3 bytes padding):
|
||||
.elem_val_imm,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
@@ -853,7 +931,6 @@ test "astgen: corpus astgen_test.zig" {
|
||||
}
|
||||
|
||||
test "astgen: corpus array_list.zig" {
|
||||
if (true) return error.SkipZigTest; // TODO: +2 ALLOC_MUT / -2 EXTENDED tag mismatch at [6639]
|
||||
const gpa = std.testing.allocator;
|
||||
try corpusCheck(gpa, @embedFile("../lib/std/array_list.zig"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user