Skip to content

Commit 9206aff

Browse files
authored
Fix #12482: false positive: misra-c2012-12.4 (#6069)
1 parent ea65c09 commit 9206aff

2 files changed

Lines changed: 51 additions & 29 deletions

File tree

addons/misra.py

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,36 +2757,55 @@ def misra_12_3(self, data):
27572757
break
27582758
prev = prev.previous
27592759

2760+
def misra_12_4_check_expr(self, expr):
2761+
if not expr.astOperand2 or not expr.astOperand1:
2762+
return
2763+
if expr.valueType is None:
2764+
return
2765+
if expr.valueType.sign is None or expr.valueType.sign != 'unsigned':
2766+
return
2767+
if expr.valueType.pointer > 0:
2768+
return
2769+
if not expr.valueType.isIntegral():
2770+
return
2771+
op1 = expr.astOperand1.getKnownIntValue()
2772+
if op1 is None:
2773+
return
2774+
op2 = expr.astOperand2.getKnownIntValue()
2775+
if op2 is None:
2776+
return
2777+
bits = bitsOfEssentialType('unsigned ' + expr.valueType.type)
2778+
if bits <= 0 or bits >= 64:
2779+
return
2780+
max_value = (1 << bits) - 1
2781+
if not is_constant_integer_expression(expr):
2782+
return
2783+
if expr.str == '+' and op1 + op2 > max_value:
2784+
self.reportError(expr, 12, 4)
2785+
elif expr.str == '-' and op1 - op2 < 0:
2786+
self.reportError(expr, 12, 4)
2787+
elif expr.str == '*' and op1 * op2 > max_value:
2788+
self.reportError(expr, 12, 4)
27602789
def misra_12_4(self, cfg):
2761-
for expr in cfg.tokenlist:
2762-
if not expr.astOperand2 or not expr.astOperand1:
2763-
continue
2764-
if expr.valueType is None:
2765-
continue
2766-
if expr.valueType.sign is None or expr.valueType.sign != 'unsigned':
2767-
continue
2768-
if expr.valueType.pointer > 0:
2769-
continue
2770-
if not expr.valueType.isIntegral():
2771-
continue
2772-
op1 = expr.astOperand1.getKnownIntValue()
2773-
if op1 is None:
2774-
continue
2775-
op2 = expr.astOperand2.getKnownIntValue()
2776-
if op2 is None:
2777-
continue
2778-
bits = bitsOfEssentialType('unsigned ' + expr.valueType.type)
2779-
if bits <= 0 or bits >= 64:
2780-
continue
2781-
max_value = (1 << bits) - 1
2782-
if not is_constant_integer_expression(expr):
2783-
continue
2784-
if expr.str == '+' and op1 + op2 > max_value:
2785-
self.reportError(expr, 12, 4)
2786-
elif expr.str == '-' and op1 - op2 < 0:
2787-
self.reportError(expr, 12, 4)
2788-
elif expr.str == '*' and op1 * op2 > max_value:
2789-
self.reportError(expr, 12, 4)
2790+
if not cfg.tokenlist:
2791+
return
2792+
expr = cfg.tokenlist[0]
2793+
while expr.next:
2794+
expr = expr.next
2795+
if expr.str == "?" and expr.astOperand2.str == ":":
2796+
known_value = expr.astOperand1.getKnownIntValue()
2797+
if known_value == 1:
2798+
tok = expr
2799+
while tok != expr.astOperand2:
2800+
self.misra_12_4_check_expr(tok)
2801+
tok = tok.next
2802+
expr = tok
2803+
while expr.str not in (";", "{", "}"):
2804+
expr = expr.next
2805+
continue
2806+
elif known_value == 0:
2807+
expr = expr.astOperand2
2808+
self.misra_12_4_check_expr(expr)
27902809

27912810

27922811
def misra_13_1(self, data):

addons/test/misra/misra-test.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,9 @@ static void misra_12_4(uint8_t t) {
997997
x = MISRA12_4a + MISRA12_4b; // 12.4
998998
x = 0u - 1u; // 12.4
999999
x = t ? 0u : (0u-1u); // 12.4
1000+
x = (0u==0u) ? 0u : (0u-1u);
1001+
x = (0u!=0u) ? 0u : (0u-1u); // 12.4
1002+
x = (0u==0u) ? 0u : (2*(0u-1u)); // 10.4
10001003
}
10011004

10021005
struct misra_13_1_t { int a; int b; };

0 commit comments

Comments
 (0)