Modified rule 14.1 (#1267)

* Modified rule 14.1

* Made suggested changes

* Added findCounterTokens

* Removed hasFloatComparison

* Improved isFloatCounterInWhileLoop

* Made all required minor changes
This commit is contained in:
Swasti Shrivastava 2018-06-04 13:42:51 +05:30 committed by Daniel Marjamäki
parent 7b106c067a
commit bdb372f929
2 changed files with 64 additions and 12 deletions

View File

@ -256,14 +256,50 @@ def getForLoopExpressions(forToken):
lpar.astOperand2.astOperand2.astOperand2] lpar.astOperand2.astOperand2.astOperand2]
def hasFloatComparison(expr): def findCounterTokens(cond):
if not expr: if not cond:
return []
if cond.str in ['&&', '||']:
c = findCounterTokens(cond.astOperand1)
c.extend(findCounterTokens(cond.astOperand2))
return c
ret = []
if ((cond.isArithmeticalOp and cond.astOperand1 and cond.astOperand2) or
(cond.isComparisonOp and cond.astOperand1 and cond.astOperand2)):
if cond.astOperand1.isName:
ret.append(cond.astOperand1)
if cond.astOperand2.isName:
ret.append(cond.astOperand2)
if cond.astOperand1.isOp:
ret.extend(findCounterTokens(cond.astOperand1))
if cond.astOperand2.isOp:
ret.extend(findCounterTokens(cond.astOperand2))
return ret
def isFloatCounterInWhileLoop(whileToken):
if not simpleMatch(whileToken, 'while ('):
return False return False
if expr.isLogicalOp: lpar = whileToken.next
return hasFloatComparison(expr.astOperand1) or hasFloatComparison(expr.astOperand2) rpar = lpar.link
if expr.isComparisonOp: counterTokens = findCounterTokens(lpar.astOperand2)
# TODO: Use ValueType whileBodyStart = None
return cppcheckdata.astIsFloat(expr.astOperand1) or cppcheckdata.astIsFloat(expr.astOperand2) if simpleMatch(rpar, ') {'):
whileBodyStart = rpar.next
elif simpleMatch(whileToken.previous, '} while') and simpleMatch(whileToken.previous.link.previous, 'do {'):
whileBodyStart = whileToken.previous.link
else:
return False
token = whileBodyStart
while (token != whileBodyStart.link):
token = token.next
for counterToken in counterTokens:
if not counterToken.valueType or not counterToken.valueType.isFloat():
continue
if token.isAssignmentOp and token.astOperand1.str == counterToken.str:
return True
if token.str == counterToken.str and token.astParent and token.astParent.str in {'++', '--'}:
return True
return False return False
@ -1107,11 +1143,16 @@ def misra_13_6(data):
def misra_14_1(data): def misra_14_1(data):
for token in data.tokenlist: for token in data.tokenlist:
if token.str != 'for': if token.str == 'for':
continue exprs = getForLoopExpressions(token)
exprs = getForLoopExpressions(token) if not exprs:
if exprs and hasFloatComparison(exprs[1]): continue
reportError(token, 14, 1) for counter in findCounterTokens(exprs[1]):
if counter.valueType and counter.valueType.isFloat():
reportError(token, 14, 1)
elif token.str == 'while':
if isFloatCounterInWhileLoop(token):
reportError(token, 14, 1)
def misra_14_2(data): def misra_14_2(data):

View File

@ -274,6 +274,17 @@ void misra_13_6() {
void misra_14_1() { void misra_14_1() {
for (float f=0.1f; f<1.0f; f += 0.1f){} // 14.1 for (float f=0.1f; f<1.0f; f += 0.1f){} // 14.1
float a = 0.0f;
int b = 10;
while ((a<100.0f) || (b > 100)) //14.1
{
a++;
}
do
{
;
} while ( a < 10.0f ); // no-warning
} }
void misra_14_2() { void misra_14_2() {