MISRA rule 7.2 Require 'u' prefix when using large unsigned integer constants (#2881)

This commit is contained in:
Lars Even Almaas 2020-11-05 13:38:09 +01:00 committed by GitHub
parent 80dee36e68
commit c1212f823f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 4 deletions

View File

@ -889,7 +889,6 @@ def tokenFollowsSequence(token, sequence):
token = prev token = prev
return True return True
class Define: class Define:
def __init__(self, directive): def __init__(self, directive):
self.args = [] self.args = []
@ -1387,6 +1386,41 @@ class MisraChecker:
if compiled.match(tok.str): if compiled.match(tok.str):
self.reportError(tok, 7, 1) 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): def misra_7_3(self, rawTokens):
compiled = re.compile(r'^[0-9.uU]+l') compiled = re.compile(r'^[0-9.uU]+l')
for tok in rawTokens: for tok in rawTokens:
@ -1418,13 +1452,13 @@ class MisraChecker:
# Check use as function parameter # Check use as function parameter
if isFunctionCall(token) and token.astOperand1 and token.astOperand1.function: if isFunctionCall(token) and token.astOperand1 and token.astOperand1.function:
functionDeclaration = 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: if functionDeclaration.tokenDef.Id == token.astOperand1.Id:
# Token is not a function call, but it is the definition of the function # Token is not a function call, but it is the definition of the function
continue continue
parametersUsed = getArguments(token)
for i in range(len(parametersUsed)): for i in range(len(parametersUsed)):
usedParameter = parametersUsed[i] usedParameter = parametersUsed[i]
parameterDefinition = functionDeclaration.argument.get(i+1) parameterDefinition = functionDeclaration.argument.get(i+1)
@ -3036,6 +3070,8 @@ class MisraChecker:
self.executeCheck(602, self.misra_6_2, cfg) self.executeCheck(602, self.misra_6_2, cfg)
if cfgNumber == 0: if cfgNumber == 0:
self.executeCheck(701, self.misra_7_1, data.rawTokens) 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(703, self.misra_7_3, data.rawTokens)
self.executeCheck(704, self.misra_7_4, cfg) self.executeCheck(704, self.misra_7_4, cfg)
self.executeCheck(811, self.misra_8_11, cfg) self.executeCheck(811, self.misra_8_11, cfg)

View File

@ -225,6 +225,30 @@ void misra_7_1() {
int x = 066; // 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() { void misra_7_3() {
long misra_7_3_a = 0l; //7.3 long misra_7_3_a = 0l; //7.3
long misra_7_3_b = 0lU; //7.3 long misra_7_3_b = 0lU; //7.3