dsp::LoopMode has no count sentinel, so five loaders bound it by its last named value #85
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
bcox/tymbal#85
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
plugin/patch_format.hreads adsp::LoopModebyte at five sites — one per envelope-bearing engine — and every one of them bounds it as<= kAlternatingrather than against a count sentinel, becausedsp/loop_mode.hdoes not have one.Found while sweeping that file during
ladder-gate. Six other bounds in the same file had the identical shape and were fixable in place, because their enums already carried sentinels:gate_modeandlpg_modemoved from<= kAmplitudeOnlyto< kModeCount, and threeVactrolGatingsites from<= kGateto< kGatingCount.ReadStripwas already reading the sentinels, so that change aligned two readers with a third rather than inventing a convention.LoopModecannot be fixed the same way. Closing it means addingkModeCounttodsp/loop_mode.hand reading it at all five sites — a change to another subsystem, which is whyladder-gatereported it rather than widening into it.Why it matters: appending a fourth loop mode needs five coordinated edits, and any site that is missed silently rejects the new value and falls back.
-Werror=switchcannot see a comparison, so nothing catches it at build time — the format simply refuses a mode the engine supports.Four other enums are read by their last named value for the same reason (no sentinel to read):
dsp::VaLadderMode(two sites),dsp::VaShaperInsert,dsp::WaveguideBore, andPartialLayerType::PhaseMode(one each).LoopModeis the one worth acting on because it is the only one with five sites.For the record, the sweep also established that the "loader ignores a sentinel its enum already has" defect is now gone from
plugin/patch_format.hentirely: twelve sites read a sentinel or a single-source predicate, and three two-valued enums are read as equality with the other value as fallback, which is exhaustive by construction.Closed by
e2c1350onmain.dsp::LoopModegainskModeCount, and all five readers now bound the byte with< kModeCount:ReadFmPairLayerReadTimelineRecordReadVaLayerReadUnvoicedLayerReadPartialLayerThe name is the one four sites in the same file already read --
dsp::LowPassGateMode::kModeCount-- so this finishes the sweep's convention rather than starting one.Verified by injection
A fourth enumerator appended to
dsp::LoopMode, which is the exact change the issue is about, failed the new test at all five readers, once each, and only at ordinal 3. Ordinals 0-2 passed throughout, so the failure was the bound and not the fixture:With the five bounds moved to
kModeCountand the injected mode still in place, the test passes -- which is what says the fix reaches all five rather than four.The regression instrument
PatchFormat.EveryReaderAcceptsEveryLoopModeTheEnumNamesbuilds one instrument carrying an FM pair with a routed secondary timeline, a VA layer, an unvoiced layer and a partial bank, and round-trips it once per ordinal belowkModeCount. It loops to the sentinel rather than over a written-out list of today's three modes, so a fourth extends its reach on its own -- a list would have made the test a sixth site to remember and no safer than the five it guards.It sits beside
AnUnknownLoopModeOrdinalDecodesToNoneAndTheLayerStillEnds, which pins the other half of the same bound: that an ordinal the enum does not name still falls back tokNone.One thing beyond what was filed
The editor had the same defect in a form the issue did not cover: two loop combos -- the VA envelope's row in
editor/va_envelope_view.handDrawTimelineControlsFor's for the FM pair ineditor/timeline_view.h-- each passed a literal3beside a three-entry label array. A fourth mode would have loaded and saved correctly and been unreachable in the picker. Both now take the count fromIM_ARRAYSIZEunder astatic_assertagainstkModeCount, matching whateditor/patch_view.halready does fordsp::ShaperShapeanddsp::VaFilterTopology. Both static_asserts fired under the injection above.Two comments that restated how many modes there are lost the count, since
kModeCountis itself an enumerator and "LoopMode has exactly three enumerators" had become false as written.Still open from this issue's tail
The four other enums read by their last named value are untouched:
dsp::VaLadderMode(two sites),dsp::VaShaperInsert,dsp::WaveguideBore, andPartialLayerType::PhaseMode. This change did not widen into them, for the reasonladder-gatedid not widen intoLoopMode.Lanes
101/101 at fastbuild, ASan and UBSan;
//plugin:preset_race_testpasses under TSan. No--config=optrun: nothing here touches the renderer or any DSP arithmetic, so no golden is at stake.