From f78314b61374a73c195b914912d9fdd59aa63c29 Mon Sep 17 00:00:00 2001 From: Swasti Shrivastava <37058682+swasti16@users.noreply.github.com> Date: Mon, 21 May 2018 15:34:20 +0530 Subject: [PATCH] Updated rule 10 4 (#1251) * Updated rule 10.4 * Updated rule 10.4 * updated rule 10.4 along with test suite --- addons/misra.py | 60 +++++++++++++++++++++++++++++++++++++--- addons/test/misra-test.c | 12 ++++++-- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/addons/misra.py b/addons/misra.py index 782b1fecf..d970974ad 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -103,6 +103,40 @@ KEYWORDS = { } +def getEssentialTypeCategory(expr): + if not expr: + return None + if expr.valueType.typeScope: + return "enum<" + expr.valueType.typeScope.className + ">" + if expr.variable: + typeToken = expr.variable.typeStartToken + while typeToken: + if typeToken.valueType: + if typeToken.valueType.type in {'bool'}: + return typeToken.valueType.type + if typeToken.valueType.type in {'float', 'double', 'long double'}: + return "float" + if typeToken.valueType.sign: + return typeToken.valueType.sign + typeToken = typeToken.next + if expr.valueType: + return expr.valueType.sign + + +def getEssentialCategorylist(operand1, operand2): + if not operand1 or not operand2: + return None, None + if (operand1.str in {'++', '--'} or + operand2.str in {'++', '--'}): + return None, None + if (operand1.valueType.pointer or + operand2.valueType.pointer): + return None, None + e1 = getEssentialTypeCategory(operand1) + e2 = getEssentialTypeCategory(operand2) + return e1, e2 + + def getEssentialType(expr): if not expr: return None @@ -646,17 +680,35 @@ def misra_9_5(rawTokens): def misra_10_4(data): + op = {'+', '-', '*', '/', '%', '&', '|', '^', '+=', '-=', '?', ':'} for token in data.tokenlist: - if token.str not in {'+', '-', '*', '/', '%', '&', '|', '^'} and not token.isComparisonOp: + if token.str not in op and not token.isComparisonOp: continue if not token.astOperand1 or not token.astOperand2: continue if not token.astOperand1.valueType or not token.astOperand2.valueType: continue - if not token.astOperand1.valueType.isIntegral() or not token.astOperand2.valueType.isIntegral(): + if ((token.astOperand1.str in op or token.astOperand1.isComparisonOp) and + (token.astOperand2.str in op or token.astOperand1.isComparisonOp)): + e1, e2 = getEssentialCategorylist(token.astOperand1.astOperand2, token.astOperand2.astOperand1) + elif token.astOperand1.str in op or token.astOperand1.isComparisonOp: + e1, e2 = getEssentialCategorylist(token.astOperand1.astOperand2, token.astOperand2) + elif token.astOperand2.str in op or token.astOperand2.isComparisonOp: + e1, e2 = getEssentialCategorylist(token.astOperand1, token.astOperand2.astOperand1) + else: + e1, e2 = getEssentialCategorylist(token.astOperand1, token.astOperand2) + if token.str == "+=" or token.str == "+": + if e1 == "char" and (e2 == "signed" or e2 == "unsigned"): + continue + if e2 == "char" and (e1 == "signed" or e1 == "unsigned"): + continue + if token.str == "-=" or token.str == "-": + if e1 == "char" and (e2 == "signed" or e2 == "unsigned"): + continue + if e1 and e2 and (e1.find('Anonymous') != -1 and (e2 == "signed" or e2 == "unsigned")): + continue + if e1 and e2 and (e2.find('Anonymous') != -1 and (e1 == "signed" or e1 == "unsigned")): continue - e1 = getEssentialType(token.astOperand1) - e2 = getEssentialType(token.astOperand2) if e1 and e2 and e1 != e2: reportError(token, 10, 4) diff --git a/addons/test/misra-test.c b/addons/test/misra-test.c index 3d8d30c82..7a76e5629 100644 --- a/addons/test/misra-test.c +++ b/addons/test/misra-test.c @@ -14,6 +14,7 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; +typedef signed int s32; typedef unsigned long long u64; //// 3.1 @@ -145,8 +146,15 @@ void misra_9_5() { int x[] = {[0]=23}; // 9.5 } -void misra_10_4(u8 x, u16 y) { - z = x + y; // 10.4 +void misra_10_4(u32 x, s32 y) { + z = x + 3; // 10.4 + enum misra_10_4_enuma { misra_10_4_A1, misra_10_4_A2, misra_10_4_A3 }; + enum misra_10_4_enumb { misra_10_4_B1, misra_10_4_B2, misra_10_4_B3 }; + if ( misra_10_4_B1 > misra_10_4_A1 ) //10.4 + { + ; + } + z = x + y //10.4 } void misra_10_6(u8 x) {