misra.py: fix false positives in 16.3 for unconditional blocks of code

This commit is contained in:
Daniel Marjamäki 2018-04-24 09:28:24 +02:00
parent bb227613bb
commit 5e31911fcd
2 changed files with 43 additions and 5 deletions

View File

@ -280,7 +280,40 @@ def getPrecedence(expr):
return -1 return -1
def noParentheses(tok1, tok2): def findRawLink(token):
tok1 = None
tok2 = None
forward = False
if token.str in '{([':
tok1 = token.str
tok2 = '})]'['{(['.find(token.str)]
forward = True
elif token.str in '})]':
tok1 = token.str
tok2 = '{(['['})]'.find(token.str)]
forward = False
else:
return None
# try to find link
indent = 0
while token:
if token.str == tok1:
indent = indent + 1
elif token.str == tok2:
if indent <= 1:
return token
indent = indent - 1
if forward == True:
token = token.next
else:
token = token.previous
# raw link not found
return None
def numberOfParentheses(tok1, tok2):
while tok1 and tok1 != tok2: while tok1 and tok1 != tok2:
if tok1.str == '(' or tok1.str == ')': if tok1.str == '(' or tok1.str == ')':
return False return False
@ -678,11 +711,11 @@ def misra_12_1(data):
if p < 2 or p > 12: if p < 2 or p > 12:
continue continue
p1 = getPrecedence(token.astOperand1) p1 = getPrecedence(token.astOperand1)
if p < p1 <= 12 and noParentheses(token.astOperand1, token): if p < p1 <= 12 and numberOfParentheses(token.astOperand1, token):
reportError(token, 12, 1) reportError(token, 12, 1)
continue continue
p2 = getPrecedence(token.astOperand2) p2 = getPrecedence(token.astOperand2)
if p < p2 <= 12 and noParentheses(token, token.astOperand2): if p < p2 <= 12 and numberOfParentheses(token, token.astOperand2):
reportError(token, 12, 1) reportError(token, 12, 1)
continue continue
@ -934,7 +967,10 @@ def misra_16_3(rawTokens):
state = STATE_BREAK state = STATE_BREAK
elif token.str == '{': elif token.str == '{':
state = STATE_OK state = STATE_OK
elif token.str == '}': elif token.str == '}' and state == STATE_BREAK:
# is this {} an unconditional block of code?
link = findRawLink(token)
if (link is None) or (link.previous is None) or (link.previous not in ':;{}'):
state = STATE_NONE state = STATE_NONE
elif token.str == 'case' or token.str == 'default': elif token.str == 'case' or token.str == 'default':
if state != STATE_OK: if state != STATE_OK:

View File

@ -239,6 +239,8 @@ void misra_16_3() {
case 10: // 16.3 case 10: // 16.3
return; // 15.5 return; // 15.5
case 11: case 11:
{ break; }
case 12:
default: break; default: break;
} }
} }