Misra: Add rule 12.1

This commit is contained in:
Daniel Marjamäki 2017-04-11 22:21:54 +02:00
parent 41a64f6d1f
commit cb274bc71d
2 changed files with 75 additions and 14 deletions

View File

@ -5,26 +5,32 @@ python misra.py misra-test.c.dump
void misra_5_1() { void misra_5_1() {
int a123456789012345678901234567890; // no-warning int a123456789012345678901234567890; // no-warning
int a1234567890123456789012345678901; // 51 int a1234567890123456789012345678901; // 5.1
} }
void misra_7_1() { void misra_7_1() {
int x = 066; // 71 int x = 066; // 7.1
} }
void misra_7_3() { void misra_7_3() {
int x = 12l; // 73 int x = 12l; // 7.3
}
void misra_12_1() {
// TODO sz = sizeof x + y; // 12.1
a = (b * c) + d;
a = b << c + d; // 12.1
} }
void misra_13_5() { void misra_13_5() {
if (x && (y++ < 123)){} // 135 if (x && (y++ < 123)){} // 13.5
} }
void misra_14_4() { void misra_14_4() {
if (x+4){} // 144 if (x+4){} // 14.4
} }
void misra_15_1() { void misra_15_1() {
goto a1; // 151 goto a1; // 15.1
} }

View File

@ -15,9 +15,9 @@ import cppcheckdata
import sys import sys
import re import re
def reportError(token, num): def reportError(token, num1, num2):
sys.stderr.write( sys.stderr.write(
'[' + token.file + ':' + str(token.linenr) + '] misra ' + str(num) + ' violation\n') '[' + token.file + ':' + str(token.linenr) + '] misra ' + str(num1) + '.' + str(num2) + ' violation\n')
def hasSideEffects(expr): def hasSideEffects(expr):
if not expr: if not expr:
@ -30,26 +30,80 @@ def hasSideEffects(expr):
def isBoolExpression(expr): def isBoolExpression(expr):
return expr and expr.str in ['!', '==', '!=', '<', '<=', '>', '>=', '&&', '||'] return expr and expr.str in ['!', '==', '!=', '<', '<=', '>', '>=', '&&', '||']
def getPrecedence(expr):
if not expr:
return 16
if not expr.astOperand1 or not expr.astOperand2:
return 16
if expr.str in ['*', '/', '%']:
return 12
if expr.str in ['+', '-']:
return 11
if expr.str in ['<<', '>>']:
return 10
if expr.str in ['<', '>', '<=', '>=']:
return 9
if expr.str in ['==', '!=']:
return 8
if expr.str == '&':
return 7
if expr.str == '^':
return 6
if expr.str == '|':
return 5
if expr.str == '&&':
return 4
if expr.str == '||':
return 3
if expr.str in ['?',':']:
return 2
if expr.isAssignmentOp:
return 1
if expr.str == ',':
return 0
return -1
def noParentheses(tok1, tok2):
while tok1 and tok1 != tok2:
if tok1.str == '(' or tok1.str == ')':
return False
tok1 = tok1.next
return tok1 == tok2
def misra_5_1(data): def misra_5_1(data):
for token in data.tokenlist: for token in data.tokenlist:
if token.isName and len(token.str) > 31: if token.isName and len(token.str) > 31:
reportError(token, 51) reportError(token, 5, 1)
def misra_7_1(rawTokens): def misra_7_1(rawTokens):
for tok in rawTokens: for tok in rawTokens:
if re.match(r'^0[0-7]+$', tok.str): if re.match(r'^0[0-7]+$', tok.str):
reportError(tok, 71) reportError(tok, 7, 1)
def misra_7_3(rawTokens): def misra_7_3(rawTokens):
for tok in rawTokens: for tok in rawTokens:
if re.match(r'^[0-9]+l+$', tok.str): if re.match(r'^[0-9]+l+$', tok.str):
reportError(tok, 73) reportError(tok, 7, 3)
def misra_12_1(data):
for token in data.tokenlist:
p = getPrecedence(token)
if p < 2 or p > 12:
continue
p1 = getPrecedence(token.astOperand1)
if p1 <= 12 and p1 > p and noParentheses(token.astOperand1,token):
reportError(token, 12, 1)
continue
p2 = getPrecedence(token.astOperand2)
if p2 <= 12 and p2 > p and noParentheses(token, token.astOperand2):
reportError(token, 12, 1)
continue
def misra_13_5(data): def misra_13_5(data):
for token in data.tokenlist: for token in data.tokenlist:
if token.isLogicalOp and hasSideEffects(token.astOperand2): if token.isLogicalOp and hasSideEffects(token.astOperand2):
reportError(token, 135) reportError(token, 13, 5)
def misra_14_4(data): def misra_14_4(data):
for token in data.tokenlist: for token in data.tokenlist:
@ -58,12 +112,12 @@ def misra_14_4(data):
if not token.astOperand1 or not (token.astOperand1.str in ['if', 'while']): if not token.astOperand1 or not (token.astOperand1.str in ['if', 'while']):
continue continue
if not isBoolExpression(token.astOperand2): if not isBoolExpression(token.astOperand2):
reportError(token, 144) reportError(token, 14, 4)
def misra_15_1(data): def misra_15_1(data):
for token in data.tokenlist: for token in data.tokenlist:
if token.str == "goto": if token.str == "goto":
reportError(token, 151) reportError(token, 15, 1)
@ -82,6 +136,7 @@ for arg in sys.argv[1:]:
if cfgNumber == 1: if cfgNumber == 1:
misra_7_1(data.rawTokens) misra_7_1(data.rawTokens)
misra_7_3(data.rawTokens) misra_7_3(data.rawTokens)
misra_12_1(cfg)
misra_13_5(cfg) misra_13_5(cfg)
misra_14_4(cfg) misra_14_4(cfg)
misra_15_1(cfg) misra_15_1(cfg)