diff --git a/addons/misra.py b/addons/misra.py index 2d8b4393f..bebe6e714 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -889,7 +889,6 @@ def tokenFollowsSequence(token, sequence): token = prev return True - class Define: def __init__(self, directive): self.args = [] @@ -1387,6 +1386,41 @@ class MisraChecker: if compiled.match(tok.str): self.reportError(tok, 7, 1) + def misra_7_2(self, data): + # Large constant numbers that are assigned to a variable should have an + # u/U suffix if the variable type is unsigned. + def reportErrorIfMissingSuffix(variable, value): + if value and value.isNumber: + if variable and variable.valueType and variable.valueType.sign == 'unsigned': + if variable.valueType.type in ['char', 'short', 'int', 'long', 'long long']: + limit = 1 << (bitsOfEssentialType(variable.valueType.type) -1) + for v in value.values: + if v.valueKind == 'known' and v.intvalue >= limit: + if not 'U' in value.str.upper(): + self.reportError(value, 7, 2) + + for token in data.tokenlist: + # Check normal variable assignment + if token.valueType and token.isNumber: + variable = getAssignedVariableToken(token) + reportErrorIfMissingSuffix(variable, token) + + # Check use as function parameter + if isFunctionCall(token) and token.astOperand1 and token.astOperand1.function: + functionDeclaration = token.astOperand1.function + + if functionDeclaration.tokenDef: + if functionDeclaration.tokenDef.Id == token.astOperand1.Id: + # Token is not a function call, but it is the definition of the function + continue + + parametersUsed = getArguments(token) + for i in range(len(parametersUsed)): + usedParameter = parametersUsed[i] + if usedParameter.isNumber: + parameterDefinition = functionDeclaration.argument.get(i+1) + reportErrorIfMissingSuffix(parameterDefinition.nameToken, usedParameter) + def misra_7_3(self, rawTokens): compiled = re.compile(r'^[0-9.uU]+l') for tok in rawTokens: @@ -1418,13 +1452,13 @@ class MisraChecker: # Check use as function parameter if isFunctionCall(token) and token.astOperand1 and token.astOperand1.function: functionDeclaration = token.astOperand1.function - parametersUsed = getArguments(token) - - if functionDeclaration and functionDeclaration.tokenDef: + + if functionDeclaration.tokenDef: if functionDeclaration.tokenDef.Id == token.astOperand1.Id: # Token is not a function call, but it is the definition of the function continue + parametersUsed = getArguments(token) for i in range(len(parametersUsed)): usedParameter = parametersUsed[i] parameterDefinition = functionDeclaration.argument.get(i+1) @@ -3036,6 +3070,8 @@ class MisraChecker: self.executeCheck(602, self.misra_6_2, cfg) if cfgNumber == 0: self.executeCheck(701, self.misra_7_1, data.rawTokens) + self.executeCheck(702, self.misra_7_2, cfg) + if cfgNumber == 0: self.executeCheck(703, self.misra_7_3, data.rawTokens) self.executeCheck(704, self.misra_7_4, cfg) self.executeCheck(811, self.misra_8_11, cfg) diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index f47dd4b52..a1ac5eea5 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -225,6 +225,30 @@ void misra_7_1() { int x = 066; // 7.1 } +void misra_7_2_call_test(int a, unsigned int b, unsigned int c) { } // 2.7 + +void misra_7_2() { + unsigned int a = 2147483647; + const unsigned int b = 2147483648U; + const unsigned int c = 2147483648; // 7.2 + unsigned int d = 2147483649; // 7.2 + + unsigned char e = 0x80; // 7.2 + unsigned char f = 0x80U; + unsigned short g = 0x8000; // 7.2 + unsigned short h = 0x8000U; + unsigned int i = 0x80000000; // 7.2 + unsigned int j = 0x80000000U; + unsigned long long k = 0x8000000000000000; // 7.2 + unsigned long long l = 0x8000000000000000ULL; + + unsigned int m = 1 + 0x80000000; // 7.2 10.4 + + misra_7_2_call_test(1, 2, 2147483648U); + misra_7_2_call_test(1, 2, 2147483648); // 7.2 + misra_7_2_call_test(1, 0x80000000, 3); // 7.2 +} + void misra_7_3() { long misra_7_3_a = 0l; //7.3 long misra_7_3_b = 0lU; //7.3