Skip to content

fix(as370): the summary counts statements flagged, not messages (#88) - #92

Merged
mgrossmann merged 1 commit into
mainfrom
fix/statements-flagged-counts-statements
Aug 29, 2026
Merged

fix(as370): the summary counts statements flagged, not messages (#88)#92
mgrossmann merged 1 commit into
mainfrom
fix/statements-flagged-counts-statements

Conversation

@mgrossmann

Copy link
Copy Markdown
Contributor

Closes #88. Splits out #91.

What IFOX00 actually does

ifnx6b.asm:443 (ERRORTN) — the line the existing cont_stmts() comment already cited, now read:

         C     COUNT,LSTMTNO            IF SAME STATEMENT NUMBER
         BE    NOCOUNT                     DON'T COUNT IT AGAIN
         ST    COUNT,LSTMTNO            ELSE SAVE IT IF DIFFERENT
         LH    R0,ERRQTY                INCREMENT NUMBER OF STATEMENTS

LSTMTNO is a single fullword, initialised to −1 (SET TO NEG TO COUNT STMT 0 ERR, line 265). So the count is adjacent-dedup over the emission order; because IFOX emits in statement order, that is "distinct statements". as370 prints per recorder, which is not statement order, so a set is the faithful reading — it gives the number IFOX would give for the same set of flagged statements.

as370 summed the per-recorder message totals: tests/undefsym.s said 5 where the oracle says NUMBER OF STATEMENTS FLAGGED = 4, because stmt 10 raises two of the five IFO188s.

A live defect closed on the way

cont_stmts() already deduped — for the continuation recorder alone, which is why cont72 was right and everything else was not. It is replaced, not copied: it counted over contd[]'s kept entries, so it under-counted past the print cap.

Both counts now come from bitmaps marked inside the recorders before their caps. The other ten still stop their printed lists at 128 with no seen-counter at all:

200 over-length operand terms, i.e. 200 flagged statements
  main:  Assembler Done   128 Statements Flagged     <- silently wrong
  here:  Assembler Done   200 Statements Flagged

bce38d8 fixed exactly this for the continuation recorder and noted the others wanted the same treatment. They get the half that decides the number, without touching their lists.

Two key spaces, and why the reconciliation is conservative

Continuation diagnostics are raised while cards are joined, before lines[] exists. So: statements keyed by lines[] index (a macro expansion's statements count individually, the way IFOX numbers them — line_org would fold them all onto the call), continuations keyed by raw card number.

They are reconciled through the origin card, and only when exactly one non-generated flagged statement carries it. Several sharing a card means a COPY'd block (whose lines keep the COPY statement's origin) or a macro expansion, where the card no longer names one statement. Over-counting is the safe direction — a count one too high is visible beside the messages; an under-count hides a diagnostic.

That guard is not theoretical. A library member's card 4 and the primary source's card 4 are different statements, and subtracting on the number alone merges them:

  member BADM card 4:  a continuation diagnostic
  source card 4:       L 1,NOSUCH  -> IFO188
  naive subtraction:   1 Statement Flagged      <- wrong, two statements

Pinned as flagged_libcard.

Measured

835 ecosystem modules (libc370 743, rexx370, ufsd, ftpd, httpd, httplua, httprexx, lua370, mvsmf, lstring370, nsf370, and nsf370 at 9012263^):

raise a diagnostic at all 13
have a library-member continuation diagnostic 0#81 removed the last of them
count changes 2: irxprobe.asm 208 → 205, nsfctcio.asm (pre-fix) 15 → 12

The 15 → 12 is #82's DCBD case exactly: five IFO188 over two statements.

No deck moves (corpus: no module moved). The RC is unchanged — errors is only a boolean for it — and is floored at one flagged statement should a severity ever be raised without one, rather than trusting that it cannot happen.

The residual, pinned rather than documented

A continuation diagnostic raised inside a macro library carries a member-relative card number that names no statement in this numbering, so it is counted on its own even when the statement it belongs to is flagged as well:

         MACRO
&L       BOTHM
&L       MVC   FIELD(8),                                              X
JUNK             0(2)
         MEND

One generated statement, badly continued and referencing an undefined symbol. IFOX00 counts 1; as370 counts 2. flagged_libmac asserts the 2 and says in its comment what the right answer is and why — so implementing #91 fails the test and brings whoever does it to the number that has to change. Closing it needs the origin (member, card) of every generated line threaded through mexp, which is the code #63, #78 and #81 came out of; not worth entering for a cosmetic counter.

Tests

undefsym now asserts the oracle's 4. Four new cases pin the properties: flagged_cap (the count survives the print cap), flagged_overlap (one statement in both spaces counts once), flagged_libcard (a member-relative card is not merged with a primary-source one), flagged_libmac (the #91 tripwire). All four fail against main where they should.

Built warning-clean with real gcc 14.2 -Werror on mvsdev as well as clang.

IFOX00's ERRORTN (ifnx6b.asm:443) holds LSTMTNO, a single fullword initialised
to -1, and increments ERRQTY only when the statement number differs from the
immediately preceding one:

      C     COUNT,LSTMTNO            IF SAME STATEMENT NUMBER
      BE    NOCOUNT                     DON'T COUNT IT AGAIN

So one statement with three diagnostics is one flagged statement. as370 summed
the per-recorder message totals instead: tests/undefsym.s reported 5 where the
oracle's listing says NUMBER OF STATEMENTS FLAGGED = 4, because stmt 10 raises
two of the five IFO188s. A statement caught by two different recorders was
counted twice as well.

cont_stmts() already deduped, for the continuation recorder alone -- which is why
cont72 was right and everything else was not. It is replaced rather than copied:
it counted over contd[]'s KEPT entries, so it under-counted past the print cap.

Both counts now come from bitmaps marked inside the recorders BEFORE their caps.
That closes a live defect in the other ten, which still stop their printed lists
at 128 entries and had no seen-counter at all: 200 over-length operand terms are
200 flagged statements, and the summary said 128, silently. bce38d8 fixed exactly
this for the continuation recorder and noted the others wanted the same
treatment; they get the half that decides the number, without touching their
lists.

Two key spaces, because continuation diagnostics are raised while cards are
joined, before lines[] exists: statements by lines[] index (so a macro
expansion's statements count individually, as IFOX numbers them -- line_org would
fold them all onto the call), continuations by raw card number. They are
reconciled through the origin card, and only when exactly one non-generated
flagged statement carries it: several sharing a card means a COPY'd block or a
macro expansion, where the card no longer names one statement, and over-counting
is the safe direction -- an under-count hides a diagnostic.

One residual, and it is a library-member one: a continuation diagnostic raised
inside a macro library carries a member-relative card number that names no
statement in this numbering, so it is counted on its own even when the statement
it belongs to is flagged as well. Filed as #91 and pinned in run.sh as a tripwire
rather than left to be discovered; closing it needs the origin (member, card) of
every generated line threaded through mexp.

Measured over 835 ecosystem modules: 13 raise a diagnostic at all, none has a
library-member continuation diagnostic (#81 removed the last of them), and the
count changes in two -- irxprobe.asm 208 -> 205, and nsfctcio.asm at 9012263^
15 -> 12, which is #82's DCBD case: five IFO188 over two statements. No deck
moves; the RC is unchanged, and is floored at one flagged statement should a
severity ever be raised without one.

run.sh pins all four properties: the count survives the print cap, one statement
in both spaces counts once, a member-relative card is not merged with a
primary-source one, and the #91 residual.
@mgrossmann
mgrossmann merged commit 8ee719c into main Aug 29, 2026
2 checks passed
@mgrossmann
mgrossmann deleted the fix/statements-flagged-counts-statements branch August 29, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

as370: "N Statements Flagged" counts messages, not statements

1 participant