Problem
The calls_out rule (cobol.py:875) takes the word after any PERFORM. _calls_out_ignore excludes only varying, until and with. These inline forms name no paragraph, yet each is recorded as a callee:
PERFORM TEST BEFORE|AFTER ... (WITH is optional) -> TEST
PERFORM FOREVER (GnuCOBOL / Micro Focus) -> FOREVER
PERFORM 3 TIMES / PERFORM WS-N TIMES (inline) -> 3 / WS-N
EXIT PERFORM [CYCLE] -> the next token (END-IF, CYCLE)
Evidence
Impact
Phantom unresolved callees in the function graph. A data name (WS-N) can collide with a real paragraph name and draw a false edge.
Acceptance criteria
Found during: crucible mainframe count audit (2026-10-04)
Reproducer
REPRO2.cbl
IDENTIFICATION DIVISION.
PROGRAM-ID. REPRO2.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-I PIC 9(4) COMP VALUE 0.
PROCEDURE DIVISION.
MAIN-PARA.
PERFORM WITH TEST AFTER VARYING WS-I FROM 1 BY 1
UNTIL WS-I > 2
DISPLAY WS-I
END-PERFORM
PERFORM TEST BEFORE UNTIL WS-I > 9
ADD 1 TO WS-I
END-PERFORM
PERFORM WORK-PARA WITH TEST AFTER UNTIL WS-I > 20
STOP RUN.
WORK-PARA.
ADD 1 TO WS-I.
REPRO3.cbl
IDENTIFICATION DIVISION.
PROGRAM-ID. REPRO3.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-I PIC 9(4) COMP VALUE 0.
01 WS-N PIC 9(4) COMP VALUE 3.
PROCEDURE DIVISION.
MAIN-PARA.
PERFORM WS-N TIMES
ADD 1 TO WS-I
END-PERFORM
PERFORM 3 TIMES
ADD 1 TO WS-I
END-PERFORM
PERFORM FOREVER
ADD 1 TO WS-I
IF WS-I > 50 EXIT PERFORM END-IF
END-PERFORM
CALL 'CBLTDLI' USING WS-I
STOP RUN.
Found by a grep-vs-engine count audit of every mainframe file in language-crucible v1.7.0 (802 of 815 files compared), on main 737cab8 and the #4290 head (now merged as c136f46).
Problem
The
calls_outrule (cobol.py:875) takes the word after any PERFORM._calls_out_ignoreexcludes onlyvarying,untilandwith. These inline forms name no paragraph, yet each is recorded as a callee:PERFORM TEST BEFORE|AFTER ...(WITH is optional) ->TESTPERFORM FOREVER(GnuCOBOL / Micro Focus) ->FOREVERPERFORM 3 TIMES/PERFORM WS-N TIMES(inline) ->3/WS-NEXIT PERFORM [CYCLE]-> the next token (END-IF,CYCLE)Evidence
zopeneditor-sample/SAM1.cbl:327PERFORM TEST AFTER VARYING I ...gives calls_out_toTEST(keyed repo).REPRO2.cblandREPRO3.cbl(below), main 737cab8 and Fix #4264: fixed / free COBOL reference format, per file and per directive #4290 head:MAIN-PARA.calls_out_to = ["WS-N", "3", "FOREVER", "END-IF", "CBLTDLI"]. Only CBLTDLI is real.PERFORM TEST BEFORE UNTIL ...givesTEST.Impact
Phantom unresolved callees in the function graph. A data name (
WS-N) can collide with a real paragraph name and draw a false edge.Acceptance criteria
test,foreverignored;<literal|identifier> TIMESwithout a following procedure name ignored;EXIT PERFORMnot read as a PERFORMPERFORM PARA-X 3 TIMES(out-of-line, still a callee)Found during: crucible mainframe count audit (2026-10-04)
Reproducer
REPRO2.cblREPRO3.cblFound by a grep-vs-engine count audit of every mainframe file in language-crucible v1.7.0 (802 of 815 files compared), on main 737cab8 and the #4290 head (now merged as c136f46).