Files
sx/src/ir/print.test.zig
agra 4defadf513 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.
2026-05-29 15:25:00 +03:00

91 lines
3.1 KiB
Zig

// Tests for print.zig
const std = @import("std");
const types = @import("types.zig");
const inst_mod = @import("inst.zig");
const mod_mod = @import("module.zig");
const print_mod = @import("print.zig");
const TypeId = types.TypeId;
const Ref = inst_mod.Ref;
const BlockId = inst_mod.BlockId;
const FuncId = inst_mod.FuncId;
const Function = inst_mod.Function;
const Module = mod_mod.Module;
const Builder = mod_mod.Builder;
test "print simple add function" {
const alloc = std.testing.allocator;
var module = Module.init(alloc);
defer module.deinit();
var b = Builder.init(&module);
const name_add = module.types.internString("add");
const name_a = module.types.internString("a");
const name_b = module.types.internString("b");
const name_entry = module.types.internString("entry");
const params = &[_]Function.Param{
.{ .name = name_a, .ty = .s64 },
.{ .name = name_b, .ty = .s64 },
};
_ = b.beginFunction(name_add, params, .s64);
const entry = b.appendBlock(name_entry, &.{});
b.switchToBlock(entry);
const a_ref = b.constInt(10, .s64);
const b_ref = b.constInt(20, .s64);
const sum = b.add(a_ref, b_ref, .s64);
b.ret(sum, .s64);
b.finalize();
var aw = std.Io.Writer.Allocating.init(alloc);
try print_mod.printModule(&module, &aw.writer);
var result = aw.writer.toArrayList();
defer result.deinit(alloc);
const output = result.items;
try std.testing.expect(std.mem.indexOf(u8, output, "func @add(a: s64, b: s64) -> s64") != null);
try std.testing.expect(std.mem.indexOf(u8, output, "entry:") != null);
try std.testing.expect(std.mem.indexOf(u8, output, "const 10 : s64") != null);
// Params occupy value slots %0/%1, so the two consts are %2/%3 and their sum %4.
try std.testing.expect(std.mem.indexOf(u8, output, "add %2, %3 : s64") != null);
try std.testing.expect(std.mem.indexOf(u8, output, "ret %4") != null);
}
test "print conditional branch" {
const alloc = std.testing.allocator;
var module = Module.init(alloc);
defer module.deinit();
var b = Builder.init(&module);
_ = b.beginFunction(module.types.internString("test"), &.{}, .s32);
const entry = b.appendBlock(module.types.internString("entry"), &.{});
const then_bb = b.appendBlock(module.types.internString("then"), &.{});
const else_bb = b.appendBlock(module.types.internString("else"), &.{});
b.switchToBlock(entry);
const cond = b.constBool(true);
b.condBr(cond, then_bb, &.{}, else_bb, &.{});
b.switchToBlock(then_bb);
const v1 = b.constInt(1, .s32);
b.ret(v1, .s32);
b.switchToBlock(else_bb);
const v2 = b.constInt(0, .s32);
b.ret(v2, .s32);
b.finalize();
var aw = std.Io.Writer.Allocating.init(alloc);
try print_mod.printModule(&module, &aw.writer);
var result = aw.writer.toArrayList();
defer result.deinit(alloc);
const output = result.items;
try std.testing.expect(std.mem.indexOf(u8, output, "cond_br %0, bb1, bb2") != null);
try std.testing.expect(std.mem.indexOf(u8, output, "then:") != null);
try std.testing.expect(std.mem.indexOf(u8, output, "else:") != null);
}