From 7926cff8cc0eaf9ac4923db6b697a0bd909e628a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 16 Apr 2017 13:09:37 +0200 Subject: [PATCH] Misra: Add rule 10.8 --- addons/misra-test.c | 8 +++++++- addons/misra.py | 47 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/addons/misra-test.c b/addons/misra-test.c index ebea52c7c..d8a2dcf2f 100644 --- a/addons/misra-test.c +++ b/addons/misra-test.c @@ -7,7 +7,9 @@ #include // 21.5 #include // 21.11 -typedef unsigned char u8; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; typedef unsigned long long u64; void misra_5_1() { @@ -24,6 +26,10 @@ void misra_7_3() { int x = 12lu; // 7.3 } +void misra_10_8(u8 x) { + y = (u16)(x+x); // 10.8 +} + void misra_11_3(u8* p) { x = (u64*)p; // 11.3 } diff --git a/addons/misra.py b/addons/misra.py index a92eefd66..a2ddc393c 100644 --- a/addons/misra.py +++ b/addons/misra.py @@ -82,6 +82,22 @@ def getEssentialType(expr): if typeToken.str in ['char', 'short', 'int', 'long', 'float', 'double']: return typeToken.str typeToken = typeToken.next + + elif expr.astOperand1 and expr.astOperand2 and expr.str in ['+', '-', '*', '/', '%', '&', '|', '^']: + e1 = getEssentialType(expr.astOperand1) + e2 = getEssentialType(expr.astOperand2) + if not e1 or not e2: + return None + types = ['bool', 'char', 'short', 'int', 'long', 'long long'] + try: + i1 = types.index(e1) + i2 = types.index(e2) + if i2 >= i1: + return types[i2] + return types[i1] + except ValueError: + return None + return None def bitsOfEssentialType(expr): @@ -94,10 +110,18 @@ def bitsOfEssentialType(expr): return SHORT_BIT if type == 'int': return INT_BIT + if type == 'long': + return LONG_BIT + if type == 'long long': + return LONG_LONG_BIT return 0 def isCast(expr): - return expr and expr.str == '(' and expr.astOperand1 == expr.link.next + if not expr or expr.str != '(' or not expr.astOperand1 or expr.astOperand2: + return False + if simpleMatch(expr,'( )'): + return False + return True def isFunctionCall(expr): if not expr: @@ -247,6 +271,26 @@ def misra_7_3(rawTokens): if re.match(r'^[0-9]+l', tok.str): reportError(tok, 7, 3) +def misra_10_8(data): + for token in data.tokenlist: + if not isCast(token): + continue + if not token.valueType or token.valueType.pointer>0: + continue + if not token.astOperand1.valueType or token.astOperand1.valueType.pointer>0: + continue + try: + intTypes = ['char', 'short', 'int', 'long', 'long long'] + index1 = intTypes.index(token.valueType.type) + e = getEssentialType(token.astOperand1) + if not e: + continue + index2 = intTypes.index(e) + if index1 > index2: + reportError(token, 10, 8) + except ValueError: + pass + def misra_11_3(data): for token in data.tokenlist: if not isCast(token): @@ -786,6 +830,7 @@ for arg in sys.argv[1:]: if cfgNumber == 1: misra_7_1(data.rawTokens) misra_7_3(data.rawTokens) + misra_10_8(cfg) misra_11_3(cfg) misra_11_4(cfg) misra_11_5(cfg)