Misra: Added 12.4

This commit is contained in:
Daniel Marjamäki 2017-04-13 11:05:04 +02:00
parent 44f9f1c065
commit b876249b6b
2 changed files with 57 additions and 2 deletions

View File

@ -34,6 +34,10 @@ void misra_12_3() {
for (i=0;i<10;i++,j++){} // 12.3 for (i=0;i<10;i++,j++){} // 12.3
} }
void misra_12_4() {
x = 123456u * 123456u; // 12.4
}
void misra_13_5() { void misra_13_5() {
if (x && (y++ < 123)){} // 13.5 if (x && (y++ < 123)){} // 13.5
} }

View File

@ -19,6 +19,12 @@ def reportError(token, num1, num2):
sys.stderr.write( sys.stderr.write(
'[' + token.file + ':' + str(token.linenr) + '] misra ' + str(num1) + '.' + str(num2) + ' violation\n') '[' + token.file + ':' + str(token.linenr) + '] misra ' + str(num1) + '.' + str(num2) + ' violation\n')
# Platform
# TODO get this from dump
CHAR_BITS = 8
SHORT_BITS = 16
INT_BITS = 32
def getEssentialType(expr): def getEssentialType(expr):
if not expr: if not expr:
return None return None
@ -34,9 +40,13 @@ def bitsOfEssentialType(expr):
type = getEssentialType(expr) type = getEssentialType(expr)
if type is None: if type is None:
return 0 return 0
if type == 'char':
return 8
# TODO get --platform type sizes # TODO get --platform type sizes
if type == 'char':
return CHAR_BITS
if type == 'short':
return SHORT_BITS
if type == 'int':
return INT_BITS
return 0 return 0
def hasSideEffects(expr): def hasSideEffects(expr):
@ -50,6 +60,27 @@ def hasSideEffects(expr):
def isBoolExpression(expr): def isBoolExpression(expr):
return expr and expr.str in ['!', '==', '!=', '<', '<=', '>', '>=', '&&', '||'] return expr and expr.str in ['!', '==', '!=', '<', '<=', '>', '>=', '&&', '||']
def isConstantExpression(expr):
if expr.isNumber:
return True
if expr.isName:
return False
if expr.astOperand1 and not isConstantExpression(expr.astOperand1):
return False
if expr.astOperand2 and not isConstantExpression(expr.astOperand2):
return False
return True
def isUnsignedInt(expr):
# TODO this function is very incomplete. use ValueType?
if not expr:
return False
if expr.isNumber:
return expr.str.find('u')>0 or expr.str.find('U')>0
if expr.str in ['+','-','*','/','%']:
return isUnsignedInt(expr.astOperand1) or isUnsignedInt(expr.astOperand2)
return False
def getPrecedence(expr): def getPrecedence(expr):
if not expr: if not expr:
return 16 return 16
@ -164,6 +195,25 @@ def misra_12_3(data):
continue continue
reportError(token, 12, 3) reportError(token, 12, 3)
def misra_12_4(data):
max_uint = 0
if INT_BITS == 16:
max_uint = 0xffff
elif INT_BITS == 32:
max_uint = 0xffffffff
else:
return
for token in data.tokenlist:
if (not isConstantExpression(token)) or (not isUnsignedInt(token)):
continue
if not token.values:
continue
for value in token.values:
if value.intvalue < 0 or value.intvalue > max_uint:
reportError(token, 12, 4)
break
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):
@ -204,6 +254,7 @@ for arg in sys.argv[1:]:
misra_12_1(cfg) misra_12_1(cfg)
misra_12_2(cfg) misra_12_2(cfg)
misra_12_3(cfg) misra_12_3(cfg)
misra_12_4(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)