From ca762683ed8ddb36a4e353df22923858631161cc Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 16:36:30 +0100 Subject: [PATCH 1/6] refactor: S10.16 re-anchor 4 drifted sender suppressions cppcheck-misra reports rule 11.3 / 11.5 / 5.7 at the cast-expression / opening-brace line, not at the closing `}` or first enum constant. The senders-cluster suppressions had drifted one line during the E11 three-TU split. SwitchingSender:59 happens to match by coincidence (its cast and closing brace are on the same source line). No behaviour change; suppressions only. --- misra_suppressions.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misra_suppressions.txt b/misra_suppressions.txt index 42f906c6..868f1d81 100644 --- a/misra_suppressions.txt +++ b/misra_suppressions.txt @@ -26,10 +26,10 @@ misra-c2012-11.3:Core/Source/SolidSyslogFormatter.c:93 misra-c2012-11.3:Core/Source/SolidSyslogMetaSd.c:51 misra-c2012-11.3:Core/Source/SolidSyslogOriginSd.c:69 misra-c2012-11.3:Core/Source/SolidSyslogPassthroughBuffer.c:49 -misra-c2012-11.3:Core/Source/SolidSyslogStreamSender.c:148 +misra-c2012-11.3:Core/Source/SolidSyslogStreamSender.c:147 misra-c2012-11.3:Core/Source/SolidSyslogSwitchingSender.c:59 misra-c2012-11.3:Core/Source/SolidSyslogTimeQualitySd.c:59 -misra-c2012-11.3:Core/Source/SolidSyslogUdpSender.c:98 +misra-c2012-11.3:Core/Source/SolidSyslogUdpSender.c:97 misra-c2012-11.3:Platform/Atomics/Source/SolidSyslogStdAtomicCounter.c:36 misra-c2012-11.3:Platform/FatFs/Source/SolidSyslogFatFsFile.c:53 misra-c2012-11.3:Platform/FreeRtos/Source/SolidSyslogFreeRtosAddress.c:8 @@ -62,7 +62,7 @@ misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWindowsFile.c:73 misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWindowsMutex.c:34 misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWinsockDatagram.c:116 misra-c2012-11.3:Platform/Windows/Source/SolidSyslogWinsockTcpStream.c:168 -misra-c2012-11.5:Core/Source/SolidSyslogUdpSender.c:202 +misra-c2012-11.5:Core/Source/SolidSyslogUdpSender.c:201 misra-c2012-11.5:Platform/Windows/Source/SolidSyslogWinsockDatagram.c:138 misra-c2012-11.5:Platform/Windows/Source/SolidSyslogWinsockTcpStream.c:312 misra-c2012-11.5:Platform/Windows/Source/SolidSyslogWinsockTcpStream.c:332 @@ -89,7 +89,7 @@ misra-c2012-5.7:Core/Source/SolidSyslogCrc16Policy.c:10 misra-c2012-5.7:Core/Source/SolidSyslogFileBlockDevice.c:16 misra-c2012-5.7:Core/Source/SolidSyslogFileBlockDevice.c:23 misra-c2012-5.7:Core/Source/SolidSyslogOriginSdPrivate.h:9 -misra-c2012-5.7:Core/Source/SolidSyslogStreamSender.c:20 +misra-c2012-5.7:Core/Source/SolidSyslogStreamSender.c:19 misra-c2012-5.7:Core/Source/SolidSyslogUdpPayload.c:5 misra-c2012-5.7:Platform/FreeRtos/Source/SolidSyslogFreeRtosSysUpTime.c:7 misra-c2012-5.7:Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c:45 From 008b44dc7654fc22eb437b3657602ab5e92c0810 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 16:38:47 +0100 Subject: [PATCH 2/6] refactor: S10.16 extend D.009 to cover rule 5.7 on anonymous enums MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck-misra fires both 2.4 (unused tag) and 5.7 (non-unique tag) on the same anonymous-enum named-constant idiom. The two findings share one syntactic shape and one rationale, so they belong under one deviation. D.009 now documents both rules. The three 5.7-on-anonymous-enum suppressions in the senders scope (UdpPayload.h, UdpPayload.c, StreamSender.c) move from the D.003 block (struct-tag repetition) to the D.009 block. D.003's wording stays narrowly about struct tags. Other historical 5.7-on-anonymous-enum sites in the D.003 block will migrate to D.009 as S10.17 / S10.18 / S10.19 review their clusters. The deviation that authorises each line is determined by the kind of identifier it lands on, not by the physical block — both blocks correctly authorise their respective sites during the transition. --- docs/misra-deviations.md | 34 +++++++++++++++++++++++++--------- misra_suppressions.txt | 11 +++++++---- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/docs/misra-deviations.md b/docs/misra-deviations.md index 6bf5a94d..6009cd63 100644 --- a/docs/misra-deviations.md +++ b/docs/misra-deviations.md @@ -598,17 +598,26 @@ Project owner — David Cozens. Recorded under --- -## D.009 — Rule 2.4: anonymous `enum` used as named-constant container +## D.009 — Rules 2.4 / 5.7: anonymous `enum` used as named-constant container -### Rule +### Rules > **Rule 2.4 (Advisory)** — A project should not contain unused tag > declarations. +> **Rule 5.7 (Required)** — A tag name shall be a unique identifier. cppcheck-misra interprets an anonymous `enum { ... };` declaration -(no enum tag, no `typedef`) as a "tag declared but unused" — the -enumerators are used as named constants but the enum type itself -is never referenced. +(no enum tag, no `typedef`) two ways: + +- as a "tag declared but unused" (2.4) — the enumerators are used + as named constants but the enum type itself is never referenced; +- as a non-unique tag (5.7) — every anonymous `enum` shares the + same empty tag identifier, so the second and subsequent ones + collide. + +Both findings originate from the same syntactic shape — the +anonymous-`enum` named-constant idiom — and are covered by a single +deviation here. ### Deviation @@ -625,14 +634,21 @@ enum ``` There are approximately 31 such declarations across `Core/` and -`Platform/*/Source/`. cppcheck-misra surfaces a subset (currently -8) under rule 2.4 once the rule 5.7 suppressions (D.003) take -effect; before then, the 5.7 check absorbs the same sites and -masks the 2.4 finding. Adding inline-suppress comments at every +`Platform/*/Source/`. Adding inline-suppress comments at every site would add visual noise next to a project-wide intentional idiom — listing them in `misra_suppressions.txt` under this deviation keeps the source clean. +**Suppression-file layout.** 5.7 anonymous-enum suppressions +were historically grouped in the D.003 block (struct-tag +repetition) because D.003 was the original 5.7 deviation; per-group +conformance stories migrate them into the D.009 block as they +review their cluster (S10.16 moved the Senders-cluster ones). +Until every group has run, both blocks contain rule 5.7 lines +and the deviation that authorises each is determined by the kind +of identifier the cppcheck-misra finding lands on (struct tag → +D.003; anonymous enum → D.009). + ### Scope - **Strict tier** — every anonymous-`enum` constants block in diff --git a/misra_suppressions.txt b/misra_suppressions.txt index 868f1d81..e2f80a8a 100644 --- a/misra_suppressions.txt +++ b/misra_suppressions.txt @@ -77,7 +77,6 @@ misra-c2012-5.7:Core/Interface/SolidSyslogFormatter.h:14 misra-c2012-5.7:Core/Interface/SolidSyslogSecurityPolicyDefinition.h:13 misra-c2012-5.7:Core/Interface/SolidSyslogTimeQuality.h:12 misra-c2012-5.7:Core/Interface/SolidSyslogTransport.h:5 -misra-c2012-5.7:Core/Interface/SolidSyslogUdpPayload.h:15 misra-c2012-5.7:Core/Source/BlockSequence.c:13 misra-c2012-5.7:Core/Source/BlockSequence.c:107 misra-c2012-5.7:Core/Source/RecordStore.c:14 @@ -89,8 +88,6 @@ misra-c2012-5.7:Core/Source/SolidSyslogCrc16Policy.c:10 misra-c2012-5.7:Core/Source/SolidSyslogFileBlockDevice.c:16 misra-c2012-5.7:Core/Source/SolidSyslogFileBlockDevice.c:23 misra-c2012-5.7:Core/Source/SolidSyslogOriginSdPrivate.h:9 -misra-c2012-5.7:Core/Source/SolidSyslogStreamSender.c:19 -misra-c2012-5.7:Core/Source/SolidSyslogUdpPayload.c:5 misra-c2012-5.7:Platform/FreeRtos/Source/SolidSyslogFreeRtosSysUpTime.c:7 misra-c2012-5.7:Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c:45 misra-c2012-5.7:Platform/OpenSsl/Source/SolidSyslogTlsStream.c:16 @@ -145,13 +142,19 @@ misra-c2012-21.10:Platform/Posix/Source/SolidSyslogPosixSysUpTime.c:3 # See docs/misra-deviations.md#d008 misra-c2012-21.6:Platform/Windows/Source/SolidSyslogWindowsFile.c:8 -# D.009 — Rule 2.4: anonymous enum used as named-constant container +# D.009 — Rules 2.4 / 5.7: anonymous enum used as named-constant container # See docs/misra-deviations.md#d009 misra-c2012-2.4:Core/Interface/SolidSyslogTransport.h:5 misra-c2012-2.4:Core/Source/BlockSequence.c:13 misra-c2012-2.4:Core/Source/BlockSequence.c:107 misra-c2012-2.4:Core/Source/RecordStore.c:14 misra-c2012-2.4:Core/Source/SolidSyslogStreamSender.c:20 +# 5.7 anonymous-enum sites — migrated from the D.003 block as per-group +# stories review their cluster. Historical sites still under D.003 will +# move here as S10.17 / S10.18 / S10.19 land. +misra-c2012-5.7:Core/Interface/SolidSyslogUdpPayload.h:15 +misra-c2012-5.7:Core/Source/SolidSyslogStreamSender.c:19 +misra-c2012-5.7:Core/Source/SolidSyslogUdpPayload.c:5 # D.010 — Rule 20.10: # stringification in _Static_assert polyfill # See docs/misra-deviations.md#d010 From 40a26fe147dfe165a89318faf853ca51846073e3 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 16:39:18 +0100 Subject: [PATCH 3/6] refactor: S10.16 satisfy MISRA 17.8 in UdpPayload_TrimToCodepointBoundary Introduce a local `trimmed` shadowing the `length` parameter so the parameter itself is not modified. Same logic, satisfies MISRA 17.8 (function parameter should not be modified). This is the senders-cluster site flagged by the S10.05 audit; the three sibling 17.8 sites in SolidSyslogFormatter.c will be fixed in S10.19. --- Core/Source/SolidSyslogUdpPayload.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Core/Source/SolidSyslogUdpPayload.c b/Core/Source/SolidSyslogUdpPayload.c index 180551a7..d6cf5846 100644 --- a/Core/Source/SolidSyslogUdpPayload.c +++ b/Core/Source/SolidSyslogUdpPayload.c @@ -29,15 +29,16 @@ size_t SolidSyslogUdpPayload_FromMtu(size_t mtu, bool isIpv6) size_t SolidSyslogUdpPayload_TrimToCodepointBoundary(const uint8_t* buffer, size_t length) { - if (length > 0U) + size_t trimmed = length; + if (trimmed > 0U) { - size_t lastCodepointStart = UdpPayload_FindLastCodepointStart(buffer, length); - if (UdpPayload_LastCodepointExtendsPastCut(buffer, length, lastCodepointStart)) + size_t lastCodepointStart = UdpPayload_FindLastCodepointStart(buffer, trimmed); + if (UdpPayload_LastCodepointExtendsPastCut(buffer, trimmed, lastCodepointStart)) { - length = lastCodepointStart; + trimmed = lastCodepointStart; } } - return length; + return trimmed; } static inline size_t UdpPayload_FindLastCodepointStart(const uint8_t* buffer, size_t length) From 58d9137b66299fa31dc8f57e9f611dc8dcca36d6 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 16:45:07 +0100 Subject: [PATCH 4/6] refactor: S10.16 narrow Null* singleton scope to satisfy MISRA 8.9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each null-object's singleton `instance` was declared at file scope but only referenced inside its `_Get()` accessor. MISRA 8.9 (an object should be defined at block scope if its identifier only appears in a single function) is satisfied by moving the declaration inside the accessor as a function-scope `static`. Lifetime and address stability are identical — `static` inside a function still has program-duration storage and a fixed address, so callers continue to receive the same pointer on every call. Twelve sites swept tree-wide: - NullAtomicCounter, NullBlockDevice, NullBuffer, NullDatagram, NullFile, NullMutex, NullResolver, NullSd, NullSecurityPolicy, NullSender, NullStore, NullStream. S10.16 scope is Senders only; the other eleven sister null-objects are picked up here because the finding-fix-when-we-see-it strategy costs less than splitting it across S10.17 / S10.18 / S10.19. No new deviation is needed — MISRA 8.9 is now satisfied across the whole null-object family. --- Core/Source/SolidSyslogNullAtomicCounter.c | 3 +-- Core/Source/SolidSyslogNullBlockDevice.c | 19 ++++++++-------- Core/Source/SolidSyslogNullBuffer.c | 3 +-- Core/Source/SolidSyslogNullDatagram.c | 13 +++++------ Core/Source/SolidSyslogNullFile.c | 25 ++++++++++----------- Core/Source/SolidSyslogNullMutex.c | 9 ++++---- Core/Source/SolidSyslogNullResolver.c | 3 +-- Core/Source/SolidSyslogNullSd.c | 3 +-- Core/Source/SolidSyslogNullSecurityPolicy.c | 11 +++++---- Core/Source/SolidSyslogNullSender.c | 3 +-- Core/Source/SolidSyslogNullStore.c | 21 +++++++++-------- Core/Source/SolidSyslogNullStream.c | 13 +++++------ 12 files changed, 57 insertions(+), 69 deletions(-) diff --git a/Core/Source/SolidSyslogNullAtomicCounter.c b/Core/Source/SolidSyslogNullAtomicCounter.c index c47ec5c7..736ec46d 100644 --- a/Core/Source/SolidSyslogNullAtomicCounter.c +++ b/Core/Source/SolidSyslogNullAtomicCounter.c @@ -6,10 +6,9 @@ static uint32_t NullAtomicCounter_Increment(struct SolidSyslogAtomicCounter* base); -static struct SolidSyslogAtomicCounter instance = {.Increment = NullAtomicCounter_Increment}; - struct SolidSyslogAtomicCounter* SolidSyslogNullAtomicCounter_Get(void) { + static struct SolidSyslogAtomicCounter instance = {.Increment = NullAtomicCounter_Increment}; return &instance; } diff --git a/Core/Source/SolidSyslogNullBlockDevice.c b/Core/Source/SolidSyslogNullBlockDevice.c index aeb42efc..26c70a57 100644 --- a/Core/Source/SolidSyslogNullBlockDevice.c +++ b/Core/Source/SolidSyslogNullBlockDevice.c @@ -32,18 +32,17 @@ static bool NullBlockDevice_Append( ); static size_t NullBlockDevice_Size(struct SolidSyslogBlockDevice* base, size_t blockIndex); -static struct SolidSyslogBlockDevice instance = { - .Acquire = NullBlockDevice_Acquire, - .Dispose = NullBlockDevice_Dispose, - .Exists = NullBlockDevice_Exists, - .Read = NullBlockDevice_Read, - .Append = NullBlockDevice_Append, - .WriteAt = NullBlockDevice_WriteAt, - .Size = NullBlockDevice_Size, -}; - struct SolidSyslogBlockDevice* SolidSyslogNullBlockDevice_Get(void) { + static struct SolidSyslogBlockDevice instance = { + .Acquire = NullBlockDevice_Acquire, + .Dispose = NullBlockDevice_Dispose, + .Exists = NullBlockDevice_Exists, + .Read = NullBlockDevice_Read, + .Append = NullBlockDevice_Append, + .WriteAt = NullBlockDevice_WriteAt, + .Size = NullBlockDevice_Size, + }; return &instance; } diff --git a/Core/Source/SolidSyslogNullBuffer.c b/Core/Source/SolidSyslogNullBuffer.c index fbae1dd1..c5b61c45 100644 --- a/Core/Source/SolidSyslogNullBuffer.c +++ b/Core/Source/SolidSyslogNullBuffer.c @@ -8,10 +8,9 @@ static bool NullBuffer_Read(struct SolidSyslogBuffer* base, void* data, size_t maxSize, size_t* bytesRead); static void NullBuffer_Write(struct SolidSyslogBuffer* base, const void* data, size_t size); -static struct SolidSyslogBuffer instance = {.Write = NullBuffer_Write, .Read = NullBuffer_Read}; - struct SolidSyslogBuffer* SolidSyslogNullBuffer_Get(void) { + static struct SolidSyslogBuffer instance = {.Write = NullBuffer_Write, .Read = NullBuffer_Read}; return &instance; } diff --git a/Core/Source/SolidSyslogNullDatagram.c b/Core/Source/SolidSyslogNullDatagram.c index 19f69b6d..672040d1 100644 --- a/Core/Source/SolidSyslogNullDatagram.c +++ b/Core/Source/SolidSyslogNullDatagram.c @@ -19,15 +19,14 @@ static enum SolidSyslogDatagramSendResult NullDatagram_SendTo( static size_t NullDatagram_MaxPayload(struct SolidSyslogDatagram* base); static void NullDatagram_Close(struct SolidSyslogDatagram* base); -static struct SolidSyslogDatagram instance = { - .Open = NullDatagram_Open, - .SendTo = NullDatagram_SendTo, - .MaxPayload = NullDatagram_MaxPayload, - .Close = NullDatagram_Close, -}; - struct SolidSyslogDatagram* SolidSyslogNullDatagram_Get(void) { + static struct SolidSyslogDatagram instance = { + .Open = NullDatagram_Open, + .SendTo = NullDatagram_SendTo, + .MaxPayload = NullDatagram_MaxPayload, + .Close = NullDatagram_Close, + }; return &instance; } diff --git a/Core/Source/SolidSyslogNullFile.c b/Core/Source/SolidSyslogNullFile.c index 0c053b56..f074557a 100644 --- a/Core/Source/SolidSyslogNullFile.c +++ b/Core/Source/SolidSyslogNullFile.c @@ -16,21 +16,20 @@ static void NullFile_Truncate(struct SolidSyslogFile* base); static bool NullFile_Exists(struct SolidSyslogFile* base, const char* path); static bool NullFile_Delete(struct SolidSyslogFile* base, const char* path); -static struct SolidSyslogFile instance = { - .Open = NullFile_Open, - .Close = NullFile_Close, - .IsOpen = NullFile_IsOpen, - .Read = NullFile_Read, - .Write = NullFile_Write, - .SeekTo = NullFile_SeekTo, - .Size = NullFile_Size, - .Truncate = NullFile_Truncate, - .Exists = NullFile_Exists, - .Delete = NullFile_Delete, -}; - struct SolidSyslogFile* SolidSyslogNullFile_Get(void) { + static struct SolidSyslogFile instance = { + .Open = NullFile_Open, + .Close = NullFile_Close, + .IsOpen = NullFile_IsOpen, + .Read = NullFile_Read, + .Write = NullFile_Write, + .SeekTo = NullFile_SeekTo, + .Size = NullFile_Size, + .Truncate = NullFile_Truncate, + .Exists = NullFile_Exists, + .Delete = NullFile_Delete, + }; return &instance; } diff --git a/Core/Source/SolidSyslogNullMutex.c b/Core/Source/SolidSyslogNullMutex.c index b48937bd..74d0ca33 100644 --- a/Core/Source/SolidSyslogNullMutex.c +++ b/Core/Source/SolidSyslogNullMutex.c @@ -5,13 +5,12 @@ static void NullMutex_Lock(struct SolidSyslogMutex* base); static void NullMutex_Unlock(struct SolidSyslogMutex* base); -static struct SolidSyslogMutex instance = { - .Lock = NullMutex_Lock, - .Unlock = NullMutex_Unlock, -}; - struct SolidSyslogMutex* SolidSyslogNullMutex_Get(void) { + static struct SolidSyslogMutex instance = { + .Lock = NullMutex_Lock, + .Unlock = NullMutex_Unlock, + }; return &instance; } diff --git a/Core/Source/SolidSyslogNullResolver.c b/Core/Source/SolidSyslogNullResolver.c index 885c9f14..fc559249 100644 --- a/Core/Source/SolidSyslogNullResolver.c +++ b/Core/Source/SolidSyslogNullResolver.c @@ -16,10 +16,9 @@ static bool NullResolver_Resolve( struct SolidSyslogAddress* result ); -static struct SolidSyslogResolver instance = {.Resolve = NullResolver_Resolve}; - struct SolidSyslogResolver* SolidSyslogNullResolver_Get(void) { + static struct SolidSyslogResolver instance = {.Resolve = NullResolver_Resolve}; return &instance; } diff --git a/Core/Source/SolidSyslogNullSd.c b/Core/Source/SolidSyslogNullSd.c index e9d72ff1..d3e47dcd 100644 --- a/Core/Source/SolidSyslogNullSd.c +++ b/Core/Source/SolidSyslogNullSd.c @@ -6,10 +6,9 @@ struct SolidSyslogFormatter; static void NullSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter); -static struct SolidSyslogStructuredData instance = {.Format = NullSd_Format}; - struct SolidSyslogStructuredData* SolidSyslogNullSd_Get(void) { + static struct SolidSyslogStructuredData instance = {.Format = NullSd_Format}; return &instance; } diff --git a/Core/Source/SolidSyslogNullSecurityPolicy.c b/Core/Source/SolidSyslogNullSecurityPolicy.c index a7529277..06f7413f 100644 --- a/Core/Source/SolidSyslogNullSecurityPolicy.c +++ b/Core/Source/SolidSyslogNullSecurityPolicy.c @@ -21,13 +21,12 @@ static bool NullSecurityPolicy_NullVerifyIntegrity(const uint8_t* data, uint16_t return true; } -static struct SolidSyslogSecurityPolicy instance = { - 0, - NullSecurityPolicy_NullComputeIntegrity, - NullSecurityPolicy_NullVerifyIntegrity, -}; - struct SolidSyslogSecurityPolicy* SolidSyslogNullSecurityPolicy_Get(void) { + static struct SolidSyslogSecurityPolicy instance = { + 0, + NullSecurityPolicy_NullComputeIntegrity, + NullSecurityPolicy_NullVerifyIntegrity, + }; return &instance; } diff --git a/Core/Source/SolidSyslogNullSender.c b/Core/Source/SolidSyslogNullSender.c index 6efd9547..347bb2ce 100644 --- a/Core/Source/SolidSyslogNullSender.c +++ b/Core/Source/SolidSyslogNullSender.c @@ -8,10 +8,9 @@ static bool NullSender_Send(struct SolidSyslogSender* base, const void* buffer, size_t size); static void NullSender_Disconnect(struct SolidSyslogSender* base); -static struct SolidSyslogSender instance = {.Send = NullSender_Send, .Disconnect = NullSender_Disconnect}; - struct SolidSyslogSender* SolidSyslogNullSender_Get(void) { + static struct SolidSyslogSender instance = {.Send = NullSender_Send, .Disconnect = NullSender_Disconnect}; return &instance; } diff --git a/Core/Source/SolidSyslogNullStore.c b/Core/Source/SolidSyslogNullStore.c index f2789a8f..dbe1ebb9 100644 --- a/Core/Source/SolidSyslogNullStore.c +++ b/Core/Source/SolidSyslogNullStore.c @@ -14,19 +14,18 @@ static size_t NullStore_GetTotalBytes(struct SolidSyslogStore* base); static size_t NullStore_GetUsedBytes(struct SolidSyslogStore* base); static bool NullStore_IsTransient(struct SolidSyslogStore* base); -static struct SolidSyslogStore instance = { - .Write = NullStore_Write, - .ReadNextUnsent = NullStore_ReadNextUnsent, - .MarkSent = NullStore_MarkSent, - .HasUnsent = NullStore_HasUnsent, - .IsHalted = NullStore_IsHalted, - .GetTotalBytes = NullStore_GetTotalBytes, - .GetUsedBytes = NullStore_GetUsedBytes, - .IsTransient = NullStore_IsTransient -}; - struct SolidSyslogStore* SolidSyslogNullStore_Get(void) { + static struct SolidSyslogStore instance = { + .Write = NullStore_Write, + .ReadNextUnsent = NullStore_ReadNextUnsent, + .MarkSent = NullStore_MarkSent, + .HasUnsent = NullStore_HasUnsent, + .IsHalted = NullStore_IsHalted, + .GetTotalBytes = NullStore_GetTotalBytes, + .GetUsedBytes = NullStore_GetUsedBytes, + .IsTransient = NullStore_IsTransient + }; return &instance; } diff --git a/Core/Source/SolidSyslogNullStream.c b/Core/Source/SolidSyslogNullStream.c index 24f211c1..da988967 100644 --- a/Core/Source/SolidSyslogNullStream.c +++ b/Core/Source/SolidSyslogNullStream.c @@ -13,15 +13,14 @@ static bool NullStream_Send(struct SolidSyslogStream* base, const void* buffer, static SolidSyslogSsize NullStream_Read(struct SolidSyslogStream* base, void* buffer, size_t size); static void NullStream_Close(struct SolidSyslogStream* base); -static struct SolidSyslogStream instance = { - .Open = NullStream_Open, - .Send = NullStream_Send, - .Read = NullStream_Read, - .Close = NullStream_Close, -}; - struct SolidSyslogStream* SolidSyslogNullStream_Get(void) { + static struct SolidSyslogStream instance = { + .Open = NullStream_Open, + .Send = NullStream_Send, + .Read = NullStream_Read, + .Close = NullStream_Close, + }; return &instance; } From abad31f8ed36ea24b733aaa1f0a54a105f9dfd81 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 17:03:20 +0100 Subject: [PATCH 5/6] refactor: S10.16 re-anchor 2.4 suppression at StreamSender anonymous enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck-misra reports rule 2.4 ("unused tag") at the `{` opening line of an anonymous enum (consistent with how it reports 5.7), not at the first constant. The StreamSender suppression was anchored at line 20 (the first constant) and worked only because the matching 5.7 suppression on the same site shadowed it via cppcheck's dedup. Once S10.16 commit ca76268 corrected the 5.7 anchor to line 19, the 2.4 finding surfaced. Bumping the 2.4 suppression line :20 → :19. Sister anonymous-enum 2.4 suppressions (BlockSequence.c:13, RecordStore.c:14, Transport.h:5) already match this convention. --- misra_suppressions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misra_suppressions.txt b/misra_suppressions.txt index e2f80a8a..2ba816f2 100644 --- a/misra_suppressions.txt +++ b/misra_suppressions.txt @@ -148,7 +148,7 @@ misra-c2012-2.4:Core/Interface/SolidSyslogTransport.h:5 misra-c2012-2.4:Core/Source/BlockSequence.c:13 misra-c2012-2.4:Core/Source/BlockSequence.c:107 misra-c2012-2.4:Core/Source/RecordStore.c:14 -misra-c2012-2.4:Core/Source/SolidSyslogStreamSender.c:20 +misra-c2012-2.4:Core/Source/SolidSyslogStreamSender.c:19 # 5.7 anonymous-enum sites — migrated from the D.003 block as per-group # stories review their cluster. Historical sites still under D.003 will # move here as S10.17 / S10.18 / S10.19 land. From 369a75217f8b4489f36039dce30d2d52f25247d7 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Fri, 22 May 2026 17:09:35 +0100 Subject: [PATCH 6/6] =?UTF-8?q?docs:=20S10.16=20DEVLOG=20entry=20=E2=80=94?= =?UTF-8?q?=20Senders=20conformance=20closeout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Records the per-group review outcome, the two decisions taken at the bend (sweep all 12 null-objects, widen D.009 to 2.4 + 5.7), and the cppcheck dedup follow-up that surfaced a second anchor drift on the StreamSender anonymous enum. --- DEVLOG.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/DEVLOG.md b/DEVLOG.md index c0bf6e63..2e8e6741 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -1,5 +1,98 @@ # Dev Log +## 2026-05-22 — S10.16 Senders conformance + +Closes S10.16 (#389). Fifth per-group conformance story in E10, +applying the S10.12 pilot recipe to the Senders cluster +(`Sender`, `NullSender`, `UdpSender`, `StreamSender`, `SwitchingSender`, +`UdpPayload` plus the E11 three-TU split files for the three pool-backed +senders). Started from the CI cppcheck-misra report against `main@ddbc81f` +— `analyze-tidy` was already clean against the cluster, so the work was +entirely on the cppcheck-misra side. + +### Findings landscape + +Six unsuppressed findings against scope in the starting CI report: + +- Four were one-line **anchor drift** in `misra_suppressions.txt`. The + 11.3 / 11.5 vtable-cast lines were anchored at the closing `}` of + the inline `SelfFromBase` (or the comment line for 11.5); cppcheck + actually reports at the cast-expression line one above. The 5.7 + anchor on the StreamSender anonymous enum was at the first constant + rather than the `{`. `SwitchingSender:59` matched by coincidence + (cast and brace on the same line). +- One **genuine fix** at `UdpPayload.c:37` — function parameter + `length` mutated in-place (rule 17.8). Introduced a local `trimmed` + copy. The audit anticipated this site; the three sibling 17.8 sites + in `SolidSyslogFormatter.c` belong to S10.19. +- One **family-wide pattern fix** at `NullSender.c:11` (rule 8.9). + The file-scope `static struct SolidSyslogSender instance = {...}` + is only used by the `_Get()` accessor — moving it inside the + accessor as a function-scope `static` narrows the identifier scope + per MISRA 8.9 with identical semantics (program-duration storage, + stable address). + +### Decisions taken at the bend + +- **8.9 — sweep all twelve sister null-objects, not just NullSender.** + The 8.9 finding fires on every `Null*.c` file (NullAtomicCounter, + NullBlockDevice, NullBuffer, NullDatagram, NullFile, NullMutex, + NullResolver, NullSd, NullSecurityPolicy, NullSender, NullStore, + NullStream). None were previously suppressed, so the cluster has + always been pending decision. The sender-only fix would have left + the family inconsistent for the duration of S10.17–S10.19, and the + diff per file is tiny. David's call: fix-when-we-see-it across + the family. No new deviation. +- **D.009 widened to cover rule 5.7 in addition to 2.4.** cppcheck + fires both rules on the same anonymous-enum named-constant idiom, + for the same syntactic shape. Splitting them across D.003 (which + is strictly about struct-tag repetition) and D.009 added noise to + no benefit. D.009's title and rule statement now name both rules; + the three Senders-scope 5.7-on-anonymous-enum suppressions + (`UdpPayload.h:15`, `StreamSender.c:19`, `UdpPayload.c:5`) + moved from the D.003 block to the D.009 block. Other historical + 5.7-on-anonymous-enum suppressions stay in the D.003 block until + S10.17 / S10.18 / S10.19 review their clusters — the deviation + that authorises each line is determined by the identifier kind, + not by the physical block. + +### Cppcheck dedup surfaced a second drift + +Re-running cppcheck after the 5.7 anchor fix surfaced rule 2.4 at +`SolidSyslogStreamSender.c:19` — the existing 2.4 suppression at +line 20 had been shadowed by the matching (mis-anchored) 5.7 at the +same site. With 5.7 correctly at line 19, the 2.4 finding emerged. +Sister anonymous-enum 2.4 suppressions (`BlockSequence.c:13`, +`RecordStore.c:14`, `Transport.h:5`) already anchor at the `{` +line. One more line bump, no new behaviour. Worth noting for +future per-group stories: removing one suppression can unmask +another on the same source line. + +### Acceptance + +- Zero in-scope `analyze-tidy` warnings (unchanged from starting state). +- Zero in-scope `cppcheck-misra` findings after the fixes (verified + against the same `ghcr.io/davidcozens/cpputest:sha-18f19e1` image + the CI uses). +- 1290/1290 tests pass on `debug` and `sanitize`. +- Tree-wide coverage 99.9% (2921/2925 lines, 602/602 functions); + uncovered lines sit in `BlockStoreStatic.c` and `PosixMutex.c` and + are pre-existing — none of the changed files lost coverage. +- clang-format clean tree-wide. +- No new deviations; no new inline suppressions; one count-bump on + D.009 (three 5.7-on-anonymous-enum lines migrated in). + +### Scope clean-up noted for the issue body + +`UdpSender` is already three-TU-split under E11 +(`SolidSyslogUdpSenderPrivate.h`, `SolidSyslogUdpSenderStatic.c`) but +the original issue body listed only `SolidSyslogUdpSender.c`. The +`SolidSyslogNullSender.{c,h}` files were also added by E11 and missing +from the original scope list. Both are folded into S10.16 — issue body +updated to reflect. + +--- + ## 2026-05-22 — S24.08 top-down function ordering sweep Closes S24.08 (#423). Pure refactoring pass: re-applied the documented