misra: fix 7.2 checking

This commit is contained in:
Daniel Marjamäki 2022-02-12 12:44:44 +01:00
parent 30cec97cc8
commit 68b00b3cfc
2 changed files with 15 additions and 67 deletions

View File

@ -1031,16 +1031,14 @@ def isNoReturnScope(tok):
# Return the token which the value is assigned to # Return the token which the value is assigned to
def getAssignedVariableToken(valueToken): def getAssignedVariableToken(vartok):
if not valueToken: if not vartok:
return None return None
if not valueToken.astParent: parent = vartok.astParent
return None while parent and parent.isArithmeticalOp:
operator = valueToken.astParent parent = parent.astParent
if operator.isAssignmentOp: if parent and parent.isAssignmentOp:
return operator.astOperand1 return parent.astOperand1
if operator.isArithmeticalOp:
return getAssignedVariableToken(operator)
return None return None
# If the value is used as a return value, return the function definition # If the value is used as a return value, return the function definition
@ -1781,41 +1779,9 @@ class MisraChecker:
self.reportError(tok, 7, 1) self.reportError(tok, 7, 1)
def misra_7_2(self, data): 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 'U' in value.str.upper():
return
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)
v = value.getKnownIntValue()
if v is not None and v >= limit:
self.reportError(value, 7, 2)
for token in data.tokenlist: for token in data.tokenlist:
# Check normal variable assignment if token.isInt and ('U' not in token.str.upper()) and token.valueType and token.valueType.sign == 'unsigned':
if token.valueType and token.isNumber: self.reportError(token, 7, 2)
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 is token.astOperand1:
# 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)
if parameterDefinition and parameterDefinition.nameToken:
reportErrorIfMissingSuffix(parameterDefinition.nameToken, usedParameter)
def misra_7_3(self, rawTokens): def misra_7_3(self, rawTokens):
compiled = re.compile(r'^[0-9.]+[Uu]*l+[Uu]*$') compiled = re.compile(r'^[0-9.]+[Uu]*l+[Uu]*$')

View File

@ -275,31 +275,13 @@ static void misra_7_1(void) {
int x = 066; // 7.1 int x = 066; // 7.1
} }
static void misra_7_2_call_test(int a, unsigned int b, unsigned int c) { } // 2.7
static void misra_7_2_call_va_test(int a, ...) { } // 2.7
static void misra_7_2(void) { static void misra_7_2(void) {
uint32_t a = 2147483647; uint32_t a = 0x7fffffff;
const uint32_t b = 2147483648U; uint32_t b = 0x80000000; // 7.2
const uint32_t c = 2147483648; // 7.2 10.3 uint32_t c = 0x80000000U;
uint32_t d = 2147483649; // 7.2 10.3 uint32_t d = 2147483647;
uint64_t e = 2147483648;
uint8_t e = 0x80; // 7.2 10.3 uint32_t f = 2147483648U;
uint8_t f = 0x80U;
uint16_t g = 0x8000; // 7.2 10.3
uint16_t h = 0x8000U;
uint32_t i = 0x80000000; // 7.2
uint32_t j = 0x80000000U;
uint64_t k = 0x8000000000000000; // TODO 7.2
uint64_t l = 0x8000000000000000ULL;
uint32_t 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
misra_7_2_call_va_test(1, 2, 3);
} }
// The addon should not generate false positives for the identifiers. // The addon should not generate false positives for the identifiers.