Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 60x 60x 60x 11x 34x 101x 4x | import type IComplianceAnnotation from "./types/IComplianceAnnotation";
/**
* 2.2 Plan -- which safety-standard rule shaped a construct, and how that is
* said in the generated C.
*
* CLAUDE.md makes this a C-Next standard, not a nicety:
*
* Whenever codegen emits code whose shape is dictated by a safety standard
* ... rather than by the obvious/naive translation, it MUST emit an
* explanatory comment directly above the generated construct. ... The
* comment names the standard + specific rule and gives a short WHY (what the
* naive form would have done and which rule it violates).
*
* The generated C is the certification artifact, so an auditor has to be able
* to trace each non-obvious construct back to the rule that shaped it -- and,
* separately, to enumerate every rule the transpiler cites at all. Three sites
* used to build these strings by hand, and one of them had drifted off the
* house form: no trailing period, and a parenthetical naming the C-Next
* construct rather than what the naive C would have done. Nothing could have
* noticed, because the form was a convention in prose and the text was a string
* literal three files apart.
*
* So the form is `render`'s, the rules are this table, and
* `__tests__/ComplianceAnnotations.test.ts` holds both to CLAUDE.md's shape.
*
* Distinct from `MisraSuppressionUtils`, which emits `cppcheck-suppress`
* directives -- a suppression tells a TOOL to stop reporting; an annotation
* tells a READER why the code looks like this.
* Adding a rule means adding a row; it cannot be added off-form.
*/
class ComplianceAnnotations {
/** The only standard cited today. Kept explicit so a second one is visible. */
private static readonly STANDARD = "MISRA C:2012";
/** ADR-026 `forever` lowers to `for (;;)`. */
static readonly FOREVER_LOOP: IComplianceAnnotation = {
rule: "14.3",
what: "infinite loop written as `for (;;)` for C-Next `forever`",
why: "`while (1)` has a controlling expression with an invariant value, which the rule forbids",
};
/** ADR-029's generated init function needs a declaration before its definition. */
static readonly INIT_PROTOTYPE: IComplianceAnnotation = {
rule: "8.4",
what: "declaration for the ADR-029 generated init function",
why: "the definition has external linkage and would otherwise be undeclared",
};
/**
* A slice copy unrolled to per-element writes.
*
* Only cited when an equivalent `memcpy` would genuinely violate the rule --
* the source type is known and differs from the destination element type, so
* the two pointer arguments would be incompatible. Matching types, an unknown
* source type, or a single element cite nothing (#1081).
*/
static sliceUnroll(
destCType: string,
srcCType: string,
): IComplianceAnnotation {
return {
rule: "21.15",
what: "slice copy unrolled to per-element writes",
why: `memcpy would pass incompatible pointer types: ${destCType}* vs ${srcCType}*`,
};
}
/**
* A float's bits reached through a union (ADR-007). Copying them into an
* integer with `memcpy` would pass a float pointer beside an integer one,
* which the rule forbids (#1760 review: the union carried no citation).
*/
static floatBitsUnion(
floatCType: string,
bitsCType: string,
): IComplianceAnnotation {
return {
rule: "21.15",
what: "float bits accessed through a union",
why: `memcpy would pass incompatible pointer types: ${floatCType}* vs ${bitsCType}*`,
};
}
/**
* The one rendering of the house form,
* `/* <Standard> Rule <N>: <what> (<why>). *\/`.
*/
static render(annotation: IComplianceAnnotation): string {
return (
`/* ${ComplianceAnnotations.STANDARD} Rule ${annotation.rule}: ` +
`${annotation.what} (${annotation.why}). */`
);
}
/**
* Every annotation this transpiler can emit.
*
* ## Its only caller is a test, deliberately
*
* That is the #1418 shape -- "a test-only caller counts as usage, so knip
* reports clean on a method whose last production caller is gone" -- and this
* branch deleted six methods that had it. So the difference is stated rather
* than left for someone to rediscover: those six were duplicates of a live
* sink, and deleting them removed a second way to do one thing. This one has
* no production caller because enumerating the set is not something the
* transpiler does while transpiling; it is what the tests hold to the house
* form, and what answers "which rules does our codegen cite?" for someone
* auditing the generated C.
*
* Without it the test would hardcode the list, and there would be two lists.
* If a sweep proposes deleting this, the question to ask is whether the
* assertion in `__tests__/ComplianceAnnotations.test.ts` still has a set to
* assert over.
*/
static all(): readonly IComplianceAnnotation[] {
return [
ComplianceAnnotations.FOREVER_LOOP,
ComplianceAnnotations.INIT_PROTOTYPE,
ComplianceAnnotations.sliceUnroll("uint8_t", "uint32_t"),
ComplianceAnnotations.floatBitsUnion("float", "uint32_t"),
];
}
}
export default ComplianceAnnotations;
|