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 | 278x 241x 37x 37x 37x 28x 9x 9x 9x 278x 278x 278x 269x 33x 236x 236x 236x 72x 164x 164x 278x 278x 278x 9x 269x 269x 269x | /**
* Handler for simple assignments (ADR-065).
*
* The fallback case: generates `target = value;` or `target op= value;`
* Used when no special handling is needed.
*
* Issue #845: MISRA 10.3 - For compound assignments on narrower types (i8, i16,
* u8, u16), expands to explicit cast: `target = (type)(target OP value);`
* Also handles int-to-float conversions with explicit casts.
*/
import IAssignmentContext from "../../../../2-Plan/types/IAssignmentContext";
import NarrowingCastHelper from "../../helpers/NarrowingCastHelper";
import TYPE_MAP from "../../types/TYPE_MAP";
import CppModeHelper from "../../helpers/CppModeHelper";
import COMPOUND_TO_BINARY from "../../types/COMPOUND_TO_BINARY";
/**
* Try to handle compound assignment on narrow types (MISRA 10.3).
* Returns the generated code if handled, null otherwise.
*/
function tryHandleCompoundNarrowingCast(
ctx: IAssignmentContext,
target: string,
): string | null {
if (!ctx.isCompound || !ctx.target.typeInfo) {
return null;
}
const baseType = ctx.target.typeInfo.baseType;
const promotedType = NarrowingCastHelper.getPromotedType(baseType);
if (promotedType !== "int" || baseType === "int") {
return null;
}
const binaryOp = COMPOUND_TO_BINARY[ctx.cOp];
Iif (!binaryOp) {
return null;
}
const cType = TYPE_MAP[baseType] ?? baseType;
const expr = `(${target} ${binaryOp} ${ctx.generatedValue})`;
const castExpr = CppModeHelper.cast(cType, expr, ctx.state);
return `${target} = ${castExpr};`;
}
/**
* Try to handle cross-type-category conversion (int <-> float).
* Returns the generated code if handled, null otherwise.
*/
function tryHandleIntToFloatConversion(
ctx: IAssignmentContext,
target: string,
): string | null {
if (ctx.isCompound || !ctx.target.typeInfo || !ctx.hasValue) {
return null;
}
const targetType = ctx.target.typeInfo.baseType;
const valueType = ctx.valueExpressionType();
if (!valueType) {
return null;
}
Eif (
!NarrowingCastHelper.isCrossTypeCategoryConversion(valueType, targetType)
) {
return null;
}
if (
!NarrowingCastHelper.isIntegerCategory(valueType) ||
!NarrowingCastHelper.isFloatCategory(targetType)
) {
return null;
}
const castedValue = NarrowingCastHelper.wrapIntToFloat(
ctx.generatedValue,
targetType,
ctx.state,
);
return `${target} ${ctx.cOp} ${castedValue};`;
}
/**
* Handle simple variable assignment.
*
* @example
* x <- 5 => x = 5;
* counter +<- 1 => counter += 1;
* i16_val &<- 0xFF => i16_val = (int16_t)(i16_val & 0xFF); // MISRA 10.3
*/
function handleSimpleAssignment(ctx: IAssignmentContext): string {
const target = ctx.renderTarget();
// Try compound assignment narrowing cast (MISRA 10.3)
const compoundResult = tryHandleCompoundNarrowingCast(ctx, target);
if (compoundResult) {
return compoundResult;
}
// Try int-to-float conversion
const conversionResult = tryHandleIntToFloatConversion(ctx, target);
Iif (conversionResult) {
return conversionResult;
}
return `${target} ${ctx.cOp} ${ctx.generatedValue};`;
}
export default handleSimpleAssignment;
|