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 129 130 131 132 133 | 13x 15x 13x 839x 792x 47x 47x 6x 41x 47x 47x 49x 49x 49x 47x 47x 13x 831x 819x 12x 12x 12x 12x 96x 96x 96x 82x 14x 14x 11x 14x 4x 12x 13x | /**
* Helper function generators for overflow-safe arithmetic and safe division.
* Extracted from CodeGenerator.ts as part of ADR-053 A5.
*
* Portability note: Uses __builtin_add_overflow, __builtin_sub_overflow, and
* __builtin_mul_overflow intrinsics (GCC 5+, Clang 3.4+). C-Next targets embedded
* systems using arm-none-eabi-gcc, so these are available. MSVC is not supported.
*
* Issue #707: Refactored to use OverflowHelperTemplates for reduced duplication.
*/
import TYPE_MAP from "../../types/TYPE_MAP";
import OverflowHelperTemplates from "./OverflowHelperTemplates";
/**
* Generate a safe arithmetic helper function (div or mod).
* Extracted to eliminate duplication between safe_div and safe_mod generation.
*/
const generateSafeArithmeticHelper = (
opName: string,
opSymbol: string,
cnxType: string,
cType: string,
): string[] => [
`static inline bool cnx_safe_${opName}_${cnxType}(${cType}* output, ${cType} numerator, ${cType} divisor, ${cType} defaultValue) {`,
` if (divisor == 0) {`,
` *output = defaultValue;`,
` return true; // Error occurred`,
` }`,
` *output = numerator ${opSymbol} divisor;`,
` return false; // Success`,
`}`,
"",
];
/**
* Generate all needed overflow helper functions
* ADR-044: Overflow helper functions with clamping or panic behavior
*/
const generateOverflowHelpers = (
usedClampOps: ReadonlySet<string>,
debugMode: boolean,
): string[] => {
if (usedClampOps.size === 0) {
return [];
}
const lines: string[] = [];
if (debugMode) {
lines.push(
"// ADR-044: Debug overflow helper functions (panic on overflow)",
"#include <limits.h>",
"#include <stdio.h>",
"#include <stdlib.h>",
"",
);
} else {
lines.push(
"// ADR-044: Overflow helper functions",
"#include <limits.h>",
"",
);
}
// Sort for deterministic output
const sortedOps = Array.from(usedClampOps).sort((a, b) => a.localeCompare(b));
for (const op of sortedOps) {
const [operation, cnxType] = op.split("_");
const helper = debugMode
? OverflowHelperTemplates.generatePanicHelper(operation, cnxType)
: OverflowHelperTemplates.generateClampHelper(operation, cnxType);
if (helper) {
lines.push(helper, "");
}
}
return lines;
};
/**
* Generate safe division helper functions for used integer types only
* ADR-051: Safe division helpers that return error flag on division by zero
*/
const generateSafeDivHelpers = (
usedSafeDivOps: ReadonlySet<string>,
): string[] => {
if (usedSafeDivOps.size === 0) {
return [];
}
const lines: string[] = [];
lines.push(
"// ADR-051: Safe division helper functions",
"#include <stdbool.h>",
"",
);
const integerTypes = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64"];
for (const cnxType of integerTypes) {
const needsDiv = usedSafeDivOps.has(`div_${cnxType}`);
const needsMod = usedSafeDivOps.has(`mod_${cnxType}`);
if (!needsDiv && !needsMod) {
continue; // Skip types that aren't used
}
const cType = TYPE_MAP[cnxType];
// Generate safe_div helper if needed
if (needsDiv) {
lines.push(...generateSafeArithmeticHelper("div", "/", cnxType, cType));
}
// Generate safe_mod helper if needed
if (needsMod) {
lines.push(...generateSafeArithmeticHelper("mod", "%", cnxType, cType));
}
}
return lines;
};
// Export as an object for consistent module pattern
const helperGenerators = {
generateOverflowHelpers,
generateSafeDivHelpers,
};
export default helperGenerators;
|