Skip to content

refactor: S10.18 Storage stack conformance#431

Merged
DavidCozens merged 6 commits into
mainfrom
refactor/s10-18-storage-conformance
May 22, 2026
Merged

refactor: S10.18 Storage stack conformance#431
DavidCozens merged 6 commits into
mainfrom
refactor/s10-18-storage-conformance

Conversation

@DavidCozens

@DavidCozens DavidCozens commented May 22, 2026

Copy link
Copy Markdown
Owner

Purpose

Closes #430. Seventh per-group conformance story in E10 — Storage stack
cluster (Store, BlockStore, RecordStore, BlockSequence,
BlockDevice, FileBlockDevice, File, plus POSIX / Windows / FatFs
file impls). Resolves the 10 unsuppressed cppcheck-misra findings in
scope baselined at run 26309037474 (main@a062d39, post-S10.17).

Change Description

Six commits, one per logical fix cluster (Patterns A–F as enumerated in
the story body), plus a clang-format follow-up and the DEVLOG.

Pattern A(void) PoolAllocator_FreeIfInUse(...) at four
*Static.c Destroy / Create-rollback sites. The pool API's bool
return is best-effort; the discards are intentional and now explicit.

Pattern B — five 17.7 sites in RecordStore.c. Three are straight
(void) memcpy(...) discards; one is (void) BlockDevice_Read on the
corruption-recovery scan path where the read-failure fall-through is
the documented fail-safe. The remaining two memcpys on the on-disk
length field were rewritten as explicit little-endian byte pack/unpack
because the bare (void) memcpy unmasked rule 21.15 (incompatible
uint8_t* / uint16_t* essential types). Pure refactor on every host
(all little-endian); existing
SolidSyslogBlockStoreTest.cpp:1555
fixture already bakes in LE layout. The explicit pack locks the on-disk
format invariant.

Pattern C — new deviation
D.012
authorising the 8.9 false positive on
Core/Source/SolidSyslogFileBlockDevice.c:20::FILE_EXTENSION.
cppcheck-misra's 8.9 tracker counts only function-scope references and
misses the file-scope enum's sizeof(FILE_EXTENSION) use; the rule
fires spuriously, and three restructure alternatives were rejected for
DRY / amplification-of-problem / inconsistency reasons (detailed in the
deviation row and DEVLOG). Divergence from the story's "no new
deviation rows" acceptance, raised as work per the per-group
conformance workflow's "raise as work" clause.

Patterns D and F — pure-review patterns: all 12 existing in-scope
suppressions (5 × D.002, 4 × D.004, 2 × D.006, 1 × D.008) reviewed
per-site; every rationale holds, no anchor drift after Patterns A–C.
No code change.

Pattern E — eight anonymous-enum 5.7 sites migrated from D.003 to
D.009. All sites confirmed as anonymous-enum-as-named-constant-container
by per-site reading; the D.003 block now contains only genuine
struct-tag repetition sites in scope. No 2.4 entries unmasked by the
migration. Side observation captured in DEVLOG: typedef-ing the
anonymous enums to give them a name eliminates 5.7+2.4 on the
declaration but immediately surfaces 10.4 at every arithmetic use site —
net-worse trade.

Test Evidence

All in-scope local gates green:

  • analyze-tidy — 0 warnings on storage-stack files (already clean on main; no regression).
  • analyze-cppcheck (with misra addon) — 0 in-scope unsuppressed findings (down from 10); 0 new findings tree-wide.
  • analyze-format — clean tree-wide within CI scope.
  • debug — 1290/1290 tests pass.
  • sanitize — 1290/1290 tests pass (ASan + UBSan).
  • coverage — 99.9% (2925/2929 lines, 602/602 functions); +1 line covered vs. main as a side effect of Pattern B's byte-pack rewrite.

Areas Affected

  • Core/Source/RecordStore.c (Pattern B — (void) casts and on-disk length byte pack/unpack; behaviour-preserving on all supported little-endian targets).
  • Core/Source/BlockSequenceStatic.c, Core/Source/RecordStoreStatic.c, Core/Source/SolidSyslogBlockStoreStatic.c (Pattern A — (void) casts).
  • docs/misra-deviations.md — new D.012.
  • misra_suppressions.txt — added D.012 single-site suppression; migrated 8 anonymous-enum 5.7 sites D.003 → D.009.
  • DEVLOG.md — session entry.

Summary by CodeRabbit

  • Refactor

    • Improved code robustness and consistency in the storage stack with enhanced error handling in critical paths.
  • Documentation

    • Updated compliance documentation with new deviation records and reorganized suppression entries for clarity.

Review Change Stack

`SolidSyslogPoolAllocator_FreeIfInUse` returns `bool` (false when the
slot wasn't ours / already free). The four call sites in pool-backed
`*Static.c` Destroy and Create-rollback paths legitimately don't care
about that return — the operation is best-effort cleanup. cppcheck-misra
17.7 flags the implicit discard.

Per-site fix: explicit `(void)` cast. Four sites:
- BlockSequenceStatic.c:37 — Destroy
- RecordStoreStatic.c:36 — Destroy
- SolidSyslogBlockStoreStatic.c:55 — Create rollback on BlockSequence failure
- SolidSyslogBlockStoreStatic.c:60 — Create rollback on RecordStore nil-object
Five 17.7 sites in RecordStore.c flagged as discarded function-call
returns. Treated per-site:

- Lines 127, 332: `(void) memcpy(...)` — copy into a byte buffer from
  an opaque source (`const void* data` or `void* dst`); cppcheck-misra
  is happy with the explicit-discard cast.
- Line 477: `(void) SolidSyslogBlockDevice_Read(...)` —
  `_IsRecordSent` deliberately falls through to `flag == SENT_FLAG_SENT`
  on a read failure during the corruption-recovery scan. The function
  doc-comment (lines 462–467) already documents the fail-safe: a
  skipped record surfaces downstream as a sequenceId gap.
- Lines 126, 250: the bare `(void) memcpy` cast didn't satisfy MISRA —
  it unmasked rule 21.15 ("pointer arguments shall be to compatible
  essential types") because the writes/reads were `uint8_t*` ↔
  `uint16_t*`. Refactored to explicit little-endian byte pack/unpack:

      lengthBytes[0] = (uint8_t) (length & 0xFFU);
      lengthBytes[1] = (uint8_t) ((length >> 8) & 0xFFU);

  Every supported target is little-endian (POSIX x86/x64/ARM, Windows
  x86/x64, FreeRTOS-Cortex-M3 on QEMU); the existing
  `SolidSyslogBlockStoreTest.cpp:1555` truncated-header fixture already
  bakes in LE layout (`{0xA5, 0x5A, 0x05}` — length 5 packed as
  `0x05 0x00`). Pure refactor on every host; the explicit shape locks
  the on-disk format invariant in code rather than leaving it implicit.

All 1290 tests green on `debug`.
cppcheck-misra fires Rule 8.9 on
`Core/Source/SolidSyslogFileBlockDevice.c:20` (`FILE_EXTENSION`),
claiming the constant's identifier appears in only a single function.
The claim is wrong — `FILE_EXTENSION` is referenced by both the
file-scope enum at line 25 (`sizeof(FILE_EXTENSION) - 1U` →
`FILENAME_SUFFIX` → `MAX_PREFIX_LENGTH`) **and** by
`_FormatBlockFilename` at line 214. The tracker counts only
function-scope references, so the enum site is invisible to it.

Experimentally verified during S10.18 that promoting the dependent
enum entries to file-scope `static const size_t` does not satisfy
the rule — instead it surfaces a second 8.9 false positive on the
new constant for the same reason. The fix path amplifies the
problem rather than resolving it.

New deviation row D.012 in `docs/misra-deviations.md`; single-site
line-anchored suppression in `misra_suppressions.txt`. The story body
specified "no new deviation rows in `docs/misra-deviations.md`" — D.012
is a divergence raised as work per the per-group conformance workflow's
"raise as work" clause, since the per-site review surfaced a genuine
cppcheck-misra tracker false positive rather than a fixable code
defect. Divergence documented in the DEVLOG entry.
… → D.009

Per-site review of every D.003 / Rule 5.7 entry in the storage stack
scope confirms all 8 are anonymous-enum sites used as named-constant
containers — not the genuine struct-tag repetition pattern D.003
originally covered. Migrated to the D.009 block:

- Core/Source/BlockSequence.c:13           (MIN/MAX_MAX_BLOCKS, SEQUENCE_MODULUS)
- Core/Source/BlockSequence.c:107          (MAX_SEQUENCE)
- Core/Source/RecordStore.c:14             (MAGIC/LENGTH/SENT_FLAG sizes + bytes)
- Core/Source/RecordStorePrivate.h:14      (RECORD_BUFFER_SIZE)
- Core/Source/SolidSyslogFileBlockDevice.c:16 (MAX_PATH_SIZE)
- Core/Source/SolidSyslogFileBlockDevice.c:23 (SEQUENCE_DIGITS, MAX_BLOCK_INDEX, etc.)
- Platform/Posix/Source/SolidSyslogPosixFile.c:18 (INVALID_FD)
- Platform/Windows/Source/SolidSyslogWindowsFile.c:24 (INVALID_FD, ACCESS_EXISTENCE_CHECK)

No corresponding 2.4 entries surfaced after the migration — the
cppcheck dedup pattern that unmasked UdpPayload.h:15 in S10.17 doesn't
fire here (no inclusion-chain narrowing in this change).

Side observation captured during the per-site review: typedef-ing
these anonymous enums to give the type a name would eliminate the
5.7+2.4 declarations site but immediately trip rule 10.4 at every
arithmetic use site (the enum's essential type stops composing with
plain integers). Net result: trades 2-per-declaration for
N-per-use-site, where N is typically larger. The D.009 deviation
implicitly documents this trade — the anonymous-enum-as-constant-
container pattern is the cheaper shape per MISRA.

Tree-wide 5.7 totals stay at 41 (21 in D.003 = genuine struct-tag
sites + 20 in D.009 = anonymous-enum sites; previously 29 + 12).

Out-of-scope D.003 5.7 entries kept where they are: CircularBuffer.c
(closed S10.12), Crc16.c / Crc16Policy.c (closed S10.13), and the
SolidSyslog.c + various platform impls deferred to S10.19. Fix when
their owning groups are next touched.
clang-format pushes the `(void) FreeIfInUse(...)` lines added by
Pattern A past the line-length limit and splits them across
`(void` / `)` on consecutive lines — ugly but what the formatter
chooses. Accepting the formatter's output rather than adding helper
scaffolding to dodge it.

Also picks up the column-alignment shift in RecordStore.c's
AssembleRecord block after Pattern B removed two of the
member-style aligned assignments.
@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5074bc46-9947-4ed8-af64-f69663307791

📥 Commits

Reviewing files that changed from the base of the PR and between a062d39 and fe37be2.

📒 Files selected for processing (7)
  • Core/Source/BlockSequenceStatic.c
  • Core/Source/RecordStore.c
  • Core/Source/RecordStoreStatic.c
  • Core/Source/SolidSyslogBlockStoreStatic.c
  • DEVLOG.md
  • docs/misra-deviations.md
  • misra_suppressions.txt

📝 Walkthrough

Walkthrough

This PR resolves ten cppcheck-misra findings in the storage stack (BlockSequence, RecordStore, BlockStore, BlockDevice, FileBlockDevice) by applying explicit void-casts to discarded return values, adjusting RecordStore length serialization to explicit little-endian packing, documenting a new MISRA deviation for a false-positive cppcheck 8.9 finding, and reorganizing suppression entries per S10.18 scope.

Changes

Storage Stack MISRA C:2012 Conformance

Layer / File(s) Summary
Pattern A: Pool allocator cleanup void casts
Core/Source/BlockSequenceStatic.c, Core/Source/RecordStoreStatic.c, Core/Source/SolidSyslogBlockStoreStatic.c
BlockSequence_Destroy, RecordStore_Destroy, and SolidSyslogBlockStore_Create failure paths explicitly cast SolidSyslogPoolAllocator_FreeIfInUse(...) returns to (void) to address Rule 17.7 (discarded return values); the pool API documents best-effort semantics, so the discard is intentional.
Pattern B: RecordStore serialization and return handling
Core/Source/RecordStore.c
Length field serialization now uses explicit little-endian byte packing/unpacking in RecordStore_AssembleRecord and RecordStore_RecordLength instead of memcpy; memcpy return in RecordStore_CopyRecordData and SolidSyslogBlockDevice_Read return in RecordStore_IsRecordSent are explicitly cast to (void) to address Rule 17.7.
MISRA deviation documentation and suppression reorganization
docs/misra-deviations.md, misra_suppressions.txt
New D.012 deviation documents Rule 8.9 false positive for FILE_EXTENSION file-scope static const referenced in both enum initializer and one function; suppression entries reorganized per Pattern E migration (eight anonymous-enum 5.7 sites move from D.003 to D.009); D.012 Rule 8.9 suppression entry added.
Work completion documentation
DEVLOG.md
Entry dated 2026-05-22 documents S10.18 (#430) closure, summarizing Patterns A–F, deviation D.012 rationale, acceptance criteria (tests, coverage, format), and carry-forward items for S10.19/S10.20.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • DavidCozens/solid-syslog#396: Introduces SolidSyslogPoolAllocator and FreeIfInUse API; this PR applies explicit void-casts at cleanup call sites introduced by that PR.
  • DavidCozens/solid-syslog#403: Updates RecordStoreStatic.c pool/destroy implementation; this PR refines the same pool allocator cleanup calls in that file.

Poem

🐰 Sixteen bytes to pack just right,
Void-cast returns from pool's might,
Little-endian lengths take their place,
MISRA deviations now documented with grace—
Storage stack shines, conformance complete!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor: S10.18 Storage stack conformance' clearly and specifically summarizes the main change: applying MISRA conformance to the storage stack cluster per the S10.18 story, resolving 10 unsuppressed findings.
Description check ✅ Passed The description fully addresses all required template sections: Purpose (closes #430), detailed Change Description (six commit patterns A–F with specifics), comprehensive Test Evidence (all gates green with metrics), and Areas Affected (all modified files listed).
Linked Issues check ✅ Passed All coding objectives from #430 are met: Pattern A adds (void) casts at four *Static.c sites [#430], Pattern B fixes five 17.7 sites in RecordStore.c with (void) casts and LE byte pack/unpack [#430], Pattern C documents D.012 deviation [#430], Patterns D/F review existing suppressions [#430], Pattern E migrates eight 5.7 sites D.003→D.009 [#430], zero new unsuppressed findings achieved, 100% coverage preserved, and all test suites pass [#430].
Out of Scope Changes check ✅ Passed All changes are in-scope to #430 S10.18 Storage stack conformance: modified files are within the declared Scope (Core/Source storage files and Platform file impls), DEVLOG and misra_deviations.md document the work, and no unrelated refactoring or feature additions are present outside the conformance patterns.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/s10-18-storage-conformance

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1296 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1520 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1248 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1248 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 86% successful (✔️ 42 passed, 🙈 7 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1136 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1248 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: No warnings
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@DavidCozens DavidCozens merged commit 1d8d6a2 into main May 22, 2026
21 checks passed
@DavidCozens DavidCozens deleted the refactor/s10-18-storage-conformance branch May 22, 2026 21:42
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.

S10.18: Storage stack conformance

1 participant