From 0a8dbd43d5f2405b8073a7490d5c91a0c824926a Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Mon, 15 Jun 2026 14:38:36 +0000 Subject: [PATCH] =?UTF-8?q?test(cfg):=20R5=20contrast=20=E2=80=94=20dense?= =?UTF-8?q?=20ceiling=20fires,=20SSA=20solver=20converges=20(#2201=20U6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gitnexus/test/unit/cfg/reaching-defs.test.ts | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/gitnexus/test/unit/cfg/reaching-defs.test.ts b/gitnexus/test/unit/cfg/reaching-defs.test.ts index 244bc8f58..994fe301e 100644 --- a/gitnexus/test/unit/cfg/reaching-defs.test.ts +++ b/gitnexus/test/unit/cfg/reaching-defs.test.ts @@ -8,6 +8,8 @@ import { } from '../../../src/core/ingestion/cfg/visitors/typescript.js'; import { computeReachingDefs, + computeReachingDefsDense, + computeReachingDefsSparse, type DefUseFact, } from '../../../src/core/ingestion/cfg/reaching-defs.js'; import type { @@ -371,6 +373,33 @@ describe('computeReachingDefs — determinism and convergence', () => { expect(capped.facts).toEqual([]); expect(capped.defCount).toBe(full.defCount); }); + + it('#2201 R5: the ceiling fires on the dense oracle but not on the SSA solver', () => { + // Contrast the two solvers on a looping CFG under a budget below the dense + // worklist's convergence: the dense oracle truncates to a sound-empty result + // (the ceiling fires), while the SSA solver — which has no fixpoint + // iteration — always converges (the ceiling that fired on the dense worklist + // effectively never fires). The facts the SSA solver computes are identical + // to the dense oracle's unbounded result. This is the #2201 acceptance: the + // blocks×64 ceiling stops firing on deep loops. + const blocks: BlockSpec[] = [{}, {}, { stmts: [stmt(3, [0], [0])] }]; + const edges: [number, number][] = [ + [0, 2], + [2, 2], // self-loop → the dense fixpoint must re-visit block 2 + [2, 1], + ]; + const denseFull = computeReachingDefsDense(mkCfg(blocks, edges, ['x'])); + const denseCeiling = computeReachingDefsDense(mkCfg(blocks, edges, ['x']), { + maxBlockVisits: 1, + }); + const sparse = computeReachingDefsSparse(mkCfg(blocks, edges, ['x']), { maxBlockVisits: 1 }); + + expect(denseFull.status).toBe('computed'); + expect(denseFull.facts.length).toBeGreaterThan(0); + expect(denseCeiling.status).toBe('truncated'); // ceiling fires on the dense worklist + expect(sparse.status).toBe('computed'); // SSA ignores the ceiling — it never fires + expect(render(sparse.facts)).toEqual(render(denseFull.facts)); // and the facts match + }); }); describe('computeReachingDefs — parser-direct acceptance (with U1/U2)', () => {