// strglobeq_test — #154 regression pin, migrated from test/wcc/989_strglobeq_run.c. // // `str == str` / `str != str` delegate to rt_streq, and cgen's str-compare // arm had an N_IDENT fast-path that ALWAYS read the header off BP+localfind(name). // For a module-GLOBAL str ident localfind→0, so it loaded saved-BP/retaddr // garbage instead of name(SB) — a silent CSTAGE miscompile (the header lives // at name(SB), not the frame). Fix mirrors #148's slice global branch: LEAQ // name(SB), load ptr/len off it. Now cs==ww, so this file is byteid-eligible. // // The bug is per-SHAPE in cgen, so each comparison shape is a separate fn the // @tests drive over three inputs: "/" (eqsep), "foo" (neither), "/usr" // (eqlong). Shapes cover const-global AND let-global operands, ident on RHS // AND on LHS, == AND !=, and a length>1 global ("/usr") so the LEN word — not // just the ptr — is read off name(SB). PRIMITIVE-only (bool) asserts — no // fmt/strconv; a wrong base/len yields a wrong boolean. package strglobeq_test; const csep: str = "/"; let lsep: str = "/"; const longsep: str = "/usr"; // rhs-ident global (p == g): const, let, len>1, and !=. fn eqr_const(p: str) bool = { return p == csep; }; fn eqr_let(p: str) bool = { return p == lsep; }; fn eqr_long(p: str) bool = { return p == longsep; }; fn ner_const(p: str) bool = { return p != csep; }; // lhs-ident global (g == p): const and len>1. fn eql_const(p: str) bool = { return csep == p; }; fn eql_long(p: str) bool = { return longsep == p; }; // Shape 1 — rhs const-global ==. @test fn rhs_const_eq() void = { assert(eqr_const("/") == true); assert(eqr_const("foo") == false); assert(eqr_const("/usr") == false); }; // Shape 2 — rhs let-global ==. @test fn rhs_let_eq() void = { assert(eqr_let("/") == true); assert(eqr_let("foo") == false); assert(eqr_let("/usr") == false); }; // Shape 3 — lhs const-global ==. @test fn lhs_const_eq() void = { assert(eql_const("/") == true); assert(eql_const("foo") == false); assert(eql_const("/usr") == false); }; // Shape 4 — rhs const-global != (negation arm). @test fn rhs_const_ne() void = { assert(ner_const("/") == false); assert(ner_const("foo") == true); assert(ner_const("/usr") == true); }; // Shape 5 — rhs len>1 const-global == (LEN word read off name(SB)). @test fn rhs_long_eq() void = { assert(eqr_long("/") == false); assert(eqr_long("foo") == false); assert(eqr_long("/usr") == true); }; // Shape 6 — lhs len>1 const-global == (LEN word, lhs sub-site). @test fn lhs_long_eq() void = { assert(eql_long("/") == false); assert(eql_long("foo") == false); assert(eql_long("/usr") == true); };