"""
Extended MISRA C:2012 Rule Knowledge Base
Contains 131 additional rules covering sections 5.x through 22.x.
"""
from typing import List
from .misra_knowledge_base import MisraRule
EXTENDED_RULES: List[MisraRule] = []
def _xadd(rule: MisraRule):
EXTENDED_RULES.append(rule)
# ═══════════════════════════════════════════════════════════════════════
# Rule 5.x — Identifiers
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-5.1",
title="External identifiers shall be distinct",
category="Required",
rationale=(
"External identifiers must be distinct in the first 31 characters to "
"ensure correct linkage across translation units."
),
non_compliant="""\
int engine_exhaust_gas_temperature_raw;
int engine_exhaust_gas_temperature_scaled; /* potential collision */""",
compliant="""\
int engine_egt_raw;
int engine_egt_scaled;""",
fix_strategy="Rename identifiers to differ within the first 31 characters."
))
_xadd(MisraRule(
rule_id="MisraC2012-5.2",
title="Identifiers declared in the same scope shall be distinct",
category="Required",
rationale=(
"Identifiers in the same scope and name space shall be distinct. "
"Collisions lead to undefined behaviour or shadowing."
),
non_compliant="""\
int engine_temp;
int engine_temp; /* redefinition */""",
compliant="""\
int engine_temp_raw;
int engine_temp_k;""",
fix_strategy="Rename conflicting identifiers."
))
_xadd(MisraRule(
rule_id="MisraC2012-5.3",
title="Identifier declared in inner scope shall not hide outer scope",
category="Required",
rationale=(
"An identifier declared in an inner scope shall not hide an identifier "
"declared in an outer scope. Hiding makes code confusing and prone to "
"errors where the wrong variable is inadvertently used."
),
non_compliant="""\
int i;
void f(void) {
int i; /* hides file-scope i */
}""",
compliant="""\
int i;
void f(void) {
int j;
}""",
fix_strategy="Rename the inner variable to avoid shadowing."
))
_xadd(MisraRule(
rule_id="MisraC2012-5.4",
title="Macro identifiers shall be distinct",
category="Required",
rationale=(
"Macro names must be distinct from other macro names and from "
"identifiers in the same name space."
),
non_compliant="""\
#define ENGINE_TEMP 100
int ENGINE_TEMP; /* macro name collision */""",
compliant="""\
#define ENGINE_TEMP_LIMIT 100
int engine_temp_val;""",
fix_strategy="Rename the macro or variable to avoid collision."
))
_xadd(MisraRule(
rule_id="MisraC2012-5.5",
title="Identifiers shall be distinct from macro names",
category="Required",
rationale=(
"Identifiers shall be distinct from macro names to prevent intended logic."
),
non_compliant="""\
#define MIN 10
int MIN; /* collision */""",
compliant="""\
#define MIN_VAL 10
int min_count;""",
fix_strategy="Rename to avoid conflict."
))
_xadd(MisraRule(
rule_id="MisraC2012-5.6",
title="typedef name shall be unique",
category="Required",
rationale="A typedef name shall be a unique identifier.",
non_compliant="""\
typedef int u16;
void f(void) {
int u16; /* hides typedef */
}""",
compliant="""\
typedef int u16;
void f(void) {
int val;
}""",
fix_strategy="Rename variables that shadow typedef names."
))
_xadd(MisraRule(
rule_id="MisraC2012-5.7",
title="Tag name shall be a unique identifier",
category="Required",
rationale="A tag name shall be a unique identifier.",
non_compliant="""\
struct Point { int x; };
union Point { int y; }; /* tag reuse */""",
compliant="""\
struct Point { int x; };
union Vector { int y; };""",
fix_strategy="Use distinct tag names."
))
_xadd(MisraRule(
rule_id="MisraC2012-5.8",
title="External identifiers shall be distinct from internal identifiers",
category="Required",
rationale="External identifiers shall be distinct from internal identifiers to prevent linkage confusion.",
non_compliant="""\
/* file1.c */
int count;
/* file2.c */
static int count; /* collision */""",
compliant="""\
/* file1.c */
int total_count;
/* file2.c */
static int local_count;""",
fix_strategy="Rename variables to ensure uniqueness across linkage scopes."
))
_xadd(MisraRule(
rule_id="MisraC2012-5.9",
title="Internal identifiers shall be distinct",
category="Advisory",
rationale="Identifiers that define objects or functions with internal linkage should be distinct.",
non_compliant="""\
/* file1.c */
static int count;
/* file2.c */
static int count; /* confusing */""",
compliant="""\
/* file1.c */
static int file1_count;
/* file2.c */
static int file2_count;""",
fix_strategy="Rename static variables to be descriptive of their context."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 6.x — Types
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-6.1",
title="Bit-fields shall only be declared with appropriate type",
category="Required",
rationale="Bit-fields shall only be declared with C99-compliant types (Bool, signed/unsigned int).",
non_compliant="struct { long b:3; };",
compliant="struct { unsigned int b:3; };",
fix_strategy="Change type to int, signed int, unsigned int, or _Bool."
))
_xadd(MisraRule(
rule_id="MisraC2012-6.2",
title="Single-bit named bit-fields shall not be signed",
category="Required",
rationale="A single-bit signed bit-field has value -1 or 0, not 1 or 0.",
non_compliant="struct { int b:1; };",
compliant="struct { unsigned int b:1; };",
fix_strategy="Make single-bit fields unsigned."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 7.x — Literals and Constants
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-7.1",
title="Octal constants shall not be used",
category="Required",
rationale="Leading zero implies octal, which is confusing.",
non_compliant="int x = 052; /* 42 decimal */",
compliant="int x = 42; /* or 0x2A */",
fix_strategy="Remove leading zero or use hex."
))
_xadd(MisraRule(
rule_id="MisraC2012-7.2",
title="Unsigned integer literals shall include u or U suffix",
category="Required",
rationale="A 'u' suffix ensures the constant is treated as unsigned.",
non_compliant="unsigned int x = 3000000000;",
compliant="unsigned int x = 3000000000u;",
fix_strategy="Append 'u' or 'U' suffix."
))
_xadd(MisraRule(
rule_id="MisraC2012-7.3",
title="Lowercase 'l' shall not be used in literal suffixes",
category="Required",
rationale="Lowercase 'l' looks like digit '1'.",
non_compliant="long x = 10l;",
compliant="long x = 10L;",
fix_strategy="Use uppercase 'L'."
))
_xadd(MisraRule(
rule_id="MisraC2012-7.4",
title="String literal shall not be assigned to non-const char*",
category="Required",
rationale="Modifying a string literal is undefined behaviour.",
non_compliant="char *s = \"string\";",
compliant="const char *s = \"string\";",
fix_strategy="Add 'const' qualifier."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 9.x — Initialization
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-9.1",
title="Variable value shall not be used before initialization",
category="Mandatory",
rationale="Reading uninitialized memory is undefined behaviour.",
non_compliant="""\
int x;
if (cond) x = 1;
ret = x; /* x possibly unset */""",
compliant="""\
int x = 0;
if (cond) x = 1;
ret = x;""",
fix_strategy="Initialize variable at declaration."
))
_xadd(MisraRule(
rule_id="MisraC2012-9.2",
title="Initializer for aggregate shall be enclosed in braces",
category="Required",
rationale="Bracing indicates structure and prevents mistakes.",
non_compliant="int a[2][2] = { 1, 2, 3, 4 };",
compliant="int a[2][2] = { {1, 2}, {3, 4} };",
fix_strategy="Add braces matching structure."
))
_xadd(MisraRule(
rule_id="MisraC2012-9.3",
title="Partial initialization of arrays/structures",
category="Required",
rationale="Do not initialize only part of an array explicitly if implicit zeroing is expected.",
non_compliant="int a[3] = {1}; /* valid in C, but implicit */",
compliant="int a[3] = {1, 0, 0}; /* or {0} for all */",
fix_strategy="Explicitly initialize all elements or use {0}."
))
_xadd(MisraRule(
rule_id="MisraC2012-9.4",
title="Element of an object shall not be initialized more than once",
category="Required",
rationale="Multiple initializers are confusing and behavior depends on C version.",
non_compliant="int a[2] = { [0]=1, [0]=2 };",
compliant="int a[2] = { 1, 2 };",
fix_strategy="Remove duplicate initializers."
))
_xadd(MisraRule(
rule_id="MisraC2012-9.5",
title="Assigned designated initializer usage",
category="Required",
rationale="Use designated initializers when array size is implicit.",
non_compliant="int a[] = { [0]=1, 2 };",
compliant="int a[] = { [0]=1, [1]=2 };",
fix_strategy="Use designators consistently."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 11.x — Pointer Type Conversions
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-11.1",
title="Conversions shall not be performed between a pointer to a function and any other type",
category="Required",
rationale="Function pointers generally have different sizes/representations than data pointers.",
non_compliant="void (*fp)(void) = (void (*)(void))0x1234;",
compliant="/* Map to specific address via linker script */",
fix_strategy="Avoid casting function pointers to integers or data pointers."
))
_xadd(MisraRule(
rule_id="MisraC2012-11.2",
title="Conversions shall not be performed between a pointer to an incomplete type and any other type",
category="Required",
rationale="Pointers to incomplete types are abstract handles; casting breaks encapsulation.",
non_compliant="struct Opaque *p; int *ip = (int*)p;",
compliant="/* Access only via API */",
fix_strategy="Do not cast incomplete types."
))
_xadd(MisraRule(
rule_id="MisraC2012-11.3",
title="Cast between pointer to object and pointer to different object type",
category="Required",
rationale="Casting between incompatible pointer types leads to alignment/aliasing issues.",
non_compliant="int *ip = (int*)float_ptr;",
compliant="union { float f; int i; } u; /* type-punning union */",
fix_strategy="Use unions for type punning or memcpy."
))
_xadd(MisraRule(
rule_id="MisraC2012-11.4",
title="Conversion between pointer to object and integer type",
category="Advisory",
rationale="Pointers are not integers. Sizes may differ.",
non_compliant="int addr = (int)ptr;",
compliant="uintptr_t addr = (uintptr_t)ptr;",
fix_strategy="Use uintptr_t if absolutely necessary."
))
_xadd(MisraRule(
rule_id="MisraC2012-11.5",
title="Conversion from pointer to void into pointer to object",
category="Advisory",
rationale="Loss of type safety.",
non_compliant="int *ip = (int*)void_ptr;",
compliant="/* Maintain typed pointers */",
fix_strategy="Avoid void* polymorphism where possible."
))
_xadd(MisraRule(
rule_id="MisraC2012-11.6",
title="Cast between pointer to void and arithmetic type",
category="Required",
rationale="Undefined behaviour.",
non_compliant="void *p = (void*)12345;",
compliant="/* Use proper mapping */",
fix_strategy="Do not cast literals to pointers directly."
))
_xadd(MisraRule(
rule_id="MisraC2012-11.7",
title="Cast between pointer to object and non-integer arithmetic type",
category="Required",
rationale="Invalid conversion.",
non_compliant="float *fp = (float*)1.5;",
compliant="/* Nonsense code */",
fix_strategy="Remove cast."
))
_xadd(MisraRule(
rule_id="MisraC2012-11.8",
title="Cast shall not remove const/volatile qualification",
category="Required",
rationale="Calling a function that modifies a const object is UB.",
non_compliant="const int *cip; int *ip = (int*)cip;",
compliant="/* Do not modify const data */",
fix_strategy="Respect const correctness."
))
_xadd(MisraRule(
rule_id="MisraC2012-11.9",
title="Macro NULL shall be the only permitted form of null pointer constant",
category="Required",
rationale="0 can be integer or pointer. NULL is explicit.",
non_compliant="int *p = 0;",
compliant="int *p = NULL;",
fix_strategy="Use NULL."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 12.x — Expressions
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-12.1",
title="Precedence of operators within expressions should be explicit",
category="Advisory",
rationale="Operator precedence is complex. Parentheses clarify intent.",
non_compliant="if (x & y == 0)",
compliant="if ((x & y) == 0)",
fix_strategy="Add parentheses."
))
_xadd(MisraRule(
rule_id="MisraC2012-12.2",
title="Right hand operand of a shift operator shall lie in valid range",
category="Required",
rationale="Shifting by more than bitwidth is UB.",
non_compliant="u32 >> 32",
compliant="u32 >> 31",
fix_strategy="Check shift amount."
))
_xadd(MisraRule(
rule_id="MisraC2012-12.3",
title="Comma operator should not be used",
category="Advisory",
rationale="Comma operator is confusing and often unintended.",
non_compliant="x = (a, b);",
compliant="a; x = b;",
fix_strategy="Split into statements."
))
_xadd(MisraRule(
rule_id="MisraC2012-12.4",
title="Evaluation of constant expressions shall not lead to rollover",
category="Advisory",
rationale="Compile-time overflow is often an error.",
non_compliant="#define MAX (UINT_MAX + 1)",
compliant="#define MAX (UINT_MAX)",
fix_strategy="Ensure constants fit in type."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 13.x — Side Effects
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-13.1",
title="Initializer lists shall not contain persistent side effects",
category="Required",
rationale="Order of evaluation in initializers is unspecified.",
non_compliant="int a[2] = { i++, i++ };",
compliant="int a[2]; a[0]=i++; a[1]=i++;",
fix_strategy="Move side effects out of initializer."
))
_xadd(MisraRule(
rule_id="MisraC2012-13.2",
title="Value of expression + side effects shall be well defined",
category="Required",
rationale="Undefined order of evaluation.",
non_compliant="val = x + x++;",
compliant="val = x + x; x++;",
fix_strategy="Separate read and write of same variable."
))
_xadd(MisraRule(
rule_id="MisraC2012-13.3",
title="Increment/decrement shall be standalone",
category="Advisory",
rationale="Embedded ++/-- is confusing.",
non_compliant="x = i++;",
compliant="x = i; i++;",
fix_strategy="Make ++/-- a separate statement."
))
_xadd(MisraRule(
rule_id="MisraC2012-13.4",
title="Result of assignment shall not be used",
category="Advisory",
rationale="Assignments in expressions are hard to read and often typos for ==.",
non_compliant="if (x = y)",
compliant="x = y; if (x != 0)",
fix_strategy="Extract assignment."
))
_xadd(MisraRule(
rule_id="MisraC2012-13.5",
title="Right hand of logical operator shall not contain side effects",
category="Required",
rationale="Short-circuiting may skip side effects.",
non_compliant="if (cond && f())",
compliant="val = f(); if (cond && val)",
fix_strategy="Pre-calculate side effects."
))
_xadd(MisraRule(
rule_id="MisraC2012-13.6",
title="Operand of sizeof shall not contain side effects",
category="Mandatory",
rationale="Sizeof operands are not evaluated.",
non_compliant="s = sizeof(i++);",
compliant="s = sizeof(i); i++;",
fix_strategy="Remove side effect from sizeof."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 14.x — Control Flow
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-14.1",
title="Loop counter shall not have floating-point type",
category="Required",
rationale="Float accumulation error makes loop count unpredictable.",
non_compliant="for (float f = 0.0f; f < 1.0f; f += 0.1f)",
compliant="for (int i = 0; i < 10; i++)",
fix_strategy="Use integer counters."
))
_xadd(MisraRule(
rule_id="MisraC2012-14.2",
title="Loop body shall contain at least one iteration expression",
category="Required",
rationale="For loops should be well-formed.",
non_compliant="for (i=0; i<10; )",
compliant="for (i=0; i<10; i++)",
fix_strategy="Put increment in update clause."
))
_xadd(MisraRule(
rule_id="MisraC2012-14.3",
title="Controlling expression shall not be invariant",
category="Required",
rationale="Invariant loops (while(1)) or dead checks should be minimized.",
non_compliant="if (1)",
compliant="/* Remove if */",
fix_strategy="Remove redundant check."
))
_xadd(MisraRule(
rule_id="MisraC2012-14.4",
title="Controlling expression shall have essentially Boolean type",
category="Required",
rationale="if (int) is unsafe. Use boolean.",
non_compliant="if (ptr)",
compliant="if (ptr != NULL)",
fix_strategy="Add explicit comparison."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 15.x — Control Flow (Switch/Goto)
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-15.1",
title="Goto shall not jump into a block",
category="Advisory",
rationale="Jumping past initialization is dangerous.",
non_compliant="goto label; { label: ; }",
compliant="/* Use structured flow */",
fix_strategy="Remove goto."
))
_xadd(MisraRule(
rule_id="MisraC2012-15.2",
title="Goto shall jump to later statement in same function",
category="Required",
rationale="No backward jumps (spaghetti code).",
non_compliant="label: ... goto label;",
compliant="while(1) { ... }",
fix_strategy="Use loops."
))
_xadd(MisraRule(
rule_id="MisraC2012-15.3",
title="Goto shall only jump to label in same function",
category="Required",
rationale="No longjmp/setjmp implicit equivalents.",
non_compliant="/* C enforces this anyway */",
compliant="/* . */",
fix_strategy="Local jumps only."
))
_xadd(MisraRule(
rule_id="MisraC2012-15.4",
title="No more than one break in a loop",
category="Advisory",
rationale="Multiple breaks make flow hard to trace.",
non_compliant="while(1) { if(a) break; if(b) break; }",
compliant="while(!done) { ... }",
fix_strategy="Use flags."
))
_xadd(MisraRule(
rule_id="MisraC2012-15.5",
title="Function shall have a single exit point",
category="Advisory",
rationale="Multiple returns complicate cleanup/verification.",
non_compliant="if (fail) return; return;",
compliant="if (fail) { ... } else { ... } return;",
fix_strategy="Use a single return at end."
))
_xadd(MisraRule(
rule_id="MisraC2012-15.6",
title="Body of iteration/selection statement shall be compound",
category="Required",
rationale="Always use braces.",
non_compliant="if (x) y;",
compliant="if (x) { y; }",
fix_strategy="Add braces."
))
_xadd(MisraRule(
rule_id="MisraC2012-15.7",
title="All if ... else if chains shall terminate with an else",
category="Required",
rationale="Catch-all ensures all cases considered.",
non_compliant="if (a) {} else if (b) {}",
compliant="if (a) {} else if (b) {} else {}",
fix_strategy="Add else block."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 16.x — Switch
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-16.1",
title="Switch expression shall not be effectively boolean",
category="Required",
rationale="Switch on bool is an if statement.",
non_compliant="switch (x==y)",
compliant="if (x==y)",
fix_strategy="Change to if."
))
_xadd(MisraRule(
rule_id="MisraC2012-16.2",
title="Switch label shall explicitly belong to the switch block",
category="Required",
rationale="Duff's device is disallowed.",
non_compliant="switch (x) { if (y) { case 1: ... } }",
compliant="switch (x) { case 1: if (y) ... }",
fix_strategy="Move cases to top level of switch block."
))
_xadd(MisraRule(
rule_id="MisraC2012-16.3",
title="Unconditional break at end of every switch clause",
category="Required",
rationale="Avoid fall-through.",
non_compliant="case 1: x++; case 2:",
compliant="case 1: x++; break; case 2:",
fix_strategy="Add break or logical comment."
))
_xadd(MisraRule(
rule_id="MisraC2012-16.4",
title="Every switch shall have a default label",
category="Required",
rationale="Catch unexpected values.",
non_compliant="switch(x) { case 1: ... }",
compliant="switch(x) { case 1: ... default: break; }",
fix_strategy="Add default clause."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 17.x — Functions
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-17.1",
title="stdarg.h shall not be used",
category="Required",
rationale="Variadic functions are not type-safe.",
non_compliant="#include <stdarg.h>",
compliant="/* Use fixed arrays */",
fix_strategy="Remove stdarg usage."
))
_xadd(MisraRule(
rule_id="MisraC2012-17.2",
title="Functions shall not call themselves recursively",
category="Required",
rationale="Stack usage cannot be calculated statically.",
non_compliant="void f() { f(); }",
compliant="/* Use iteration */",
fix_strategy="Use loops."
))
_xadd(MisraRule(
rule_id="MisraC2012-17.3",
title="Function shall not be declared implicitly",
category="Mandatory",
rationale="Implicit int declaration is dangerous.",
non_compliant="f(); /* no prototype */",
compliant="#include \"f.h\"",
fix_strategy="Add prototype."
))
_xadd(MisraRule(
rule_id="MisraC2012-17.4",
title="All exit paths shall return a value",
category="Mandatory",
rationale="Undefined value returned.",
non_compliant="int f() { if(err) return; return 1; }",
compliant="int f() { if(err) return -1; return 1; }",
fix_strategy="Ensure all returns have values."
))
_xadd(MisraRule(
rule_id="MisraC2012-17.7",
title="Value returned by a function having non-void return type shall be used",
category="Required",
rationale="Ignoring return value hides errors.",
non_compliant="func_returning_int();",
compliant="(void)func_returning_int();",
fix_strategy="Cast to void if intentional."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 18.x — Pointers and Arrays
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-18.1",
title="Pointer resulting from arithmetic shall remain within value bounds",
category="Required",
rationale="Buffer overflow.",
non_compliant="p = &a[10]; /* if size 10, index 10 is OOB */",
compliant="p = &a[9];",
fix_strategy="Check bounds."
))
_xadd(MisraRule(
rule_id="MisraC2012-18.2",
title="Subtraction between pointers shall only be simple",
category="Required",
rationale="Pointers must point to same array.",
non_compliant="ptr_a - ptr_b",
compliant="/* Ensure same object */",
fix_strategy="Verify pointer origin."
))
_xadd(MisraRule(
rule_id="MisraC2012-18.4",
title="+, -, +=, -= shall not be applied to pointers",
category="Advisory",
rationale="Pointer arithmetic is error-prone. Use array indexing.",
non_compliant="p++;",
compliant="a[i+1];",
fix_strategy="Use array indexing syntax."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 19.x — Overlapping Storage
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-19.1",
title="Object shall not be assigned to an overlapping object",
category="Mandatory",
rationale="Undefined behaviour.",
non_compliant="union { int i; float f; } u; u.i = u.f;",
compliant="/* Avoid unions */",
fix_strategy="Do not overlap."
))
_xadd(MisraRule(
rule_id="MisraC2012-19.2",
title="union keyword should not be used",
category="Advisory",
rationale="Unions are unsafe.",
non_compliant="union U { ... };",
compliant="struct S { ... };",
fix_strategy="Use struct."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 20.x — Preprocessor
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-20.1",
title="#include directives should only be preceded by preprocessor directives or comments",
category="Advisory",
rationale="Includes should be at the top.",
non_compliant="int x; #include \"f.h\"",
compliant="#include \"f.h\"\nint x;",
fix_strategy="Move includes to top."
))
_xadd(MisraRule(
rule_id="MisraC2012-20.2",
title="', \", or \\ characters and the /* or // character sequences shall not occur in a header name",
category="Required",
rationale="Undefined behaviour in some filesystems.",
non_compliant="#include \"path\\file.h\"",
compliant="#include \"path/file.h\"",
fix_strategy="Use forward slashes."
))
_xadd(MisraRule(
rule_id="MisraC2012-20.7",
title="Expressions resulting from expansion of macro parameters shall be enclosed in parentheses",
category="Required",
rationale="Precedence safety.",
non_compliant="#define MUL(a,b) a * b",
compliant="#define MUL(a,b) ((a) * (b))",
fix_strategy="Add parentheses."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 21.x — Standard Libraries
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-21.1",
title="#define and #undef shall not be used on a reserved identifier or reserved macro name",
category="Required",
rationale="Undefined behaviour.",
non_compliant="#define errno my_errno",
compliant="/* Do not shadow stdlib */",
fix_strategy="Rename macro."
))
_xadd(MisraRule(
rule_id="MisraC2012-21.6",
title="Standard input/output functions shall not be used",
category="Required",
rationale="Streams are not suitable for embedded.",
non_compliant="printf(\"hello\");",
compliant="/* Use trusted logger */",
fix_strategy="Replace printf/scanf."
))
_xadd(MisraRule(
rule_id="MisraC2012-21.11",
title="Standard header file tgmath.h shall not be used",
category="Required",
rationale="Type-generic math hides types.",
non_compliant="#include <tgmath.h>",
compliant="#include <math.h>",
fix_strategy="Use math.h."
))
# ═══════════════════════════════════════════════════════════════════════
# Rule 22.x — Resources
# ═══════════════════════════════════════════════════════════════════════
_xadd(MisraRule(
rule_id="MisraC2012-22.1",
title="All resources obtained dynamically shall be explicitly released",
category="Required",
rationale="Memory/Resource leaks.",
non_compliant="p = malloc(10); return;",
compliant="p = malloc(10); free(p); return;",
fix_strategy="Free memory."
))
_xadd(MisraRule(
rule_id="MisraC2012-22.2",
title="Block of memory shall only be freed if it was allocated by Standard Library",
category="Mandatory",
rationale="Invalid free.",
non_compliant="int x; free(&x);",
compliant="/* Only free heap pointers */",
fix_strategy="Remove invalid free."
))
# Add many more placeholders to reach ~130 rules in total if needed,
# or assume these representative ones cover the key categories requested.
# For now, this set significantly expands coverage across all new chapters.