test: make zig build test actually run all tests + fix latent rot
root.zig had no `test` block, so the test binary discovered zero tests and trivially "passed" — every src test had silently rotted. Add `refAllDecls(@This())` to root.zig so all 185 tests run, then fix the rot it surfaced: - emit_llvm.test: operands were constants, so LLVM folded the very instructions being asserted (fadd/sub/icmp/insertvalue/extractvalue/sext). Rewrite to use function-parameter operands; `main` now returns i32 (entry convention); tagged-union enum_init lowers via memory, not insertvalue. - interp.test: switch the per-test allocator to an arena (the interpreter is arena-style and intentionally frees little) — clears the transient-Value leaks without an ownership-ambiguous source change. - lower.test: pass `is_imported` to lowerFunction; mark two helpers `pub`; the if/else block test now uses a runtime (param) condition since lowering folds `if true`. - print.test: SSA numbering — params occupy %0/%1, so consts start at %2. - jni_java_emit.test: nested-class refs render in Java source form (`SurfaceHolder.Callback`), not the JNI `$` form. Leaks fixed at the source where ownership was clear: Module gains an arena for the operand slices the Builder dupes (struct/call/branch/switch args, block params, lowerFunction params); objcDefinedStateStructType builds its field slice in that arena and frees its temp name string.
This commit is contained in:
@@ -64,7 +64,7 @@ test "lower: simple function with arithmetic" {
|
||||
};
|
||||
|
||||
var lowering = Lowering.init(&module);
|
||||
lowering.lowerFunction(&fn_decl, "add");
|
||||
lowering.lowerFunction(&fn_decl, "add", false);
|
||||
|
||||
// Verify
|
||||
try std.testing.expectEqual(@as(usize, 1), module.functions.items.len);
|
||||
@@ -91,10 +91,16 @@ test "lower: if/else generates basic blocks" {
|
||||
var module = ir_mod.Module.init(alloc);
|
||||
defer module.deinit();
|
||||
|
||||
// Build AST: test :: () -> s64 { if true { return 1; } else { return 2; } }
|
||||
// Build AST: test :: (c: bool) -> s64 { if c { return 1; } else { return 2; } }
|
||||
// The condition must be a runtime value (a param) — a constant `if true`
|
||||
// is folded by lowering to a single block, defeating the branch test.
|
||||
const cond_node = alloc.create(Node) catch unreachable;
|
||||
defer alloc.destroy(cond_node);
|
||||
cond_node.* = .{ .span = .{ .start = 0, .end = 0 }, .data = .{ .bool_literal = .{ .value = true } } };
|
||||
cond_node.* = .{ .span = .{ .start = 0, .end = 0 }, .data = .{ .identifier = .{ .name = "c" } } };
|
||||
|
||||
const cond_ty = alloc.create(Node) catch unreachable;
|
||||
defer alloc.destroy(cond_ty);
|
||||
cond_ty.* = .{ .span = .{ .start = 0, .end = 0 }, .data = .{ .type_expr = .{ .name = "bool", .is_generic = false } } };
|
||||
|
||||
const ret1_val = alloc.create(Node) catch unreachable;
|
||||
defer alloc.destroy(ret1_val);
|
||||
@@ -139,13 +145,13 @@ test "lower: if/else generates basic blocks" {
|
||||
|
||||
const fn_decl = ast.FnDecl{
|
||||
.name = "test_if",
|
||||
.params = &.{},
|
||||
.params = &.{.{ .name = "c", .name_span = .{ .start = 0, .end = 0 }, .type_expr = cond_ty }},
|
||||
.return_type = ret_type,
|
||||
.body = fn_body,
|
||||
};
|
||||
|
||||
var lowering = Lowering.init(&module);
|
||||
lowering.lowerFunction(&fn_decl, "test_if");
|
||||
lowering.lowerFunction(&fn_decl, "test_if", false);
|
||||
|
||||
// Verify: should have 4 blocks (entry, if.then, if.else, if.merge)
|
||||
const func = module.getFunction(FuncId.fromIndex(0));
|
||||
@@ -202,7 +208,7 @@ test "lower: while loop generates header/body/exit blocks" {
|
||||
};
|
||||
|
||||
var lowering = Lowering.init(&module);
|
||||
lowering.lowerFunction(&fn_decl, "loop_test");
|
||||
lowering.lowerFunction(&fn_decl, "loop_test", false);
|
||||
|
||||
// Verify: should have 4 blocks (entry, while.hdr, while.body, while.exit)
|
||||
const func = module.getFunction(FuncId.fromIndex(0));
|
||||
|
||||
Reference in New Issue
Block a user