fix(as370): &SYSLIST(n,m) reaches inside a sublist operand (#94) - #96
Merged
Conversation
&SYSLIST(n) is the n'th positional operand; &SYSLIST(n,m) is the m'th element of
that operand's sublist. The resolver evaluated the whole subscript text as a
single expression -- eval_seta("1,1") stops at the comma and yields 1 -- so the
second subscript was dropped and the reference returned the operand entire,
parentheses included.
Where the result was used as a name, the generated statement carried
`(ALPHA,8,GAMMA)` and the module died of IFO016, an over-long name field. That
diagnostic was correct about what it saw and pointed nowhere near the cause:
nothing in the source has an over-long name.
One subscript per level now, applying sub_elem once each. The scan is also
balanced rather than strchr(')'), since a subscript may carry its own
parentheses -- &SYSLIST((&I+1),1) -- and the first ')' is then in the wrong
place; its own test case covers that.
Measured on the guest rather than assumed (JOB02901, deck and listing committed
as tests/ref/syslist.obj and tests/listref/ifox-listing-syslist.txt). The fixture
probes a three-element sublist AND a plain operand, because the plain one decides
whether per-level substitution needs a special case:
operand 1 = (ALPHA,8,GAMMA) (1,1)=ALPHA (1,2)=8 (1,3)=GAMMA
operand 2 = BETA (2,1)=BETA (2,2)=null
It does not: sub_elem already returns a value with no leading '(' for index 1 and
nothing beyond, which is exactly what the guest does. The deck now matches IFOX00
byte for byte through the ESD and TXT cards, the END card differing only in the
translator IDR as everywhere else.
The named-parameter form &P(m) was already right and stays a control in the
fixture; it shares sub_elem and only ever needs one level.
sub_elem's tail copy moves from strncpy to the file's own scopy. gcc 14.2 reads
the pair as a truncating copy once the new caller makes the sizes visible at the
inline site -- OUT holds 96 bytes and V can be the whole &SYSLIST buffer. The
truncation is intended and bounded as it always was; scopy says so and
terminates.
The ecosystem is untouched -- 826 modules unchanged, no corpus module moved. On a
local tree of real IBM MVS assembler, 6 more of a 277-module sample assemble
clean, none lost.
Noted while capturing, and not fixed here: IFOX rejected the first version of the
fixture with 22 IFO006 UNDEFINED VARIABLE SYMBOL, because Assembler XF requires
LCLA/LCLC for a macro's local SET symbols and as370 accepts them undeclared.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #94.
&SYSLIST(n)is the n'th positional operand;&SYSLIST(n,m)is the m'th element of that operand's sublist. The resolver evaluated the whole subscript text as a single expression —eval_seta("1,1")stops at the comma and yields 1 — so the second subscript was dropped and the reference returned the operand entire, parentheses included.Used as a name, the generated statement carried
(ALPHA,8,GAMMA)and the module died ofIFO016, an over-long name field. That diagnostic was correct about what it saw and pointed nowhere near the cause: nothing in the source has an over-long name.Measured, not assumed
capture.pyon mvsdev, JOB02901, RC 0 — deck and listing both committed (tests/ref/syslist.obj,tests/listref/ifox-listing-syslist.txt). The fixture probes a three-element sublist and a plain operand on purpose, because the plain one decides whether per-level substitution needs a special case:(n,1)(n,2)(n,3)(ALPHA,8,GAMMA)ALPHA8GAMMABETABETAIt does not:
sub_elemalready returns a value with no leading(for index 1 and nothing beyond, which is exactly what the guest does. The deck is byte-identical through ESD and TXT, the END card differing only in the translator IDR as everywhere else.The first capture attempt was rejected — 22 statements flagged,
IFO006 UNDEFINED VARIABLE SYMBOL. Assembler XF requiresLCLA/LCLCfor a macro's local SET symbols and as370 accepts them undeclared. A separate leniency, noted in the commit and the listref README, not fixed here.The change
One subscript per level, applying
sub_elemonce each. The scan is also balanced rather thanstrchr(')'): a subscript may carry its own parentheses —&SYSLIST((&I+1),1)— and the first)is then in the wrong place.syslist_nestedcovers that on its own.The named-parameter form
&P(m)was already right and stays in the fixture as a control; it sharessub_elemand only ever needs one level.sub_elem's tail copy moves fromstrncpyto the file's ownscopy. gcc 14.2 reads the pair as a truncating copy once the new caller makes the sizes visible at the inline site —outholds 96 bytes andvcan be the whole&SYSLISTbuffer. The truncation is intended and bounded as it always was;scopysays so and terminates.Verification
tests/corpus/check.shno module movedtests/run.shALL SAMPLES BYTE-IDENTICAL TO IFOX00tests/listref/check.shBoth new cases fail against
main(expected RC 0, got 8/a parenthesised subscript truncated the expression).On a local tree of real IBM MVS assembler — not committed here — 6 more of a 277-module spread sample assemble clean, none lost. Measured against
mainincluding #93, so this is #94's own contribution.Built warning-clean with real gcc 14.2
-Werroron mvsdev as well as clang; it caught thestrncpytruncation above, which clang accepts.