Skip to content

Commit c1212f8

Browse files
authored
MISRA rule 7.2 Require 'u' prefix when using large unsigned integer constants (#2881)
1 parent 80dee36 commit c1212f8

2 files changed

Lines changed: 64 additions & 4 deletions

File tree

addons/misra.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,6 @@ def tokenFollowsSequence(token, sequence):
889889
token = prev
890890
return True
891891

892-
893892
class Define:
894893
def __init__(self, directive):
895894
self.args = []
@@ -1387,6 +1386,41 @@ def misra_7_1(self, rawTokens):
13871386
if compiled.match(tok.str):
13881387
self.reportError(tok, 7, 1)
13891388

1389+
def misra_7_2(self, data):
1390+
# Large constant numbers that are assigned to a variable should have an
1391+
# u/U suffix if the variable type is unsigned.
1392+
def reportErrorIfMissingSuffix(variable, value):
1393+
if value and value.isNumber:
1394+
if variable and variable.valueType and variable.valueType.sign == 'unsigned':
1395+
if variable.valueType.type in ['char', 'short', 'int', 'long', 'long long']:
1396+
limit = 1 << (bitsOfEssentialType(variable.valueType.type) -1)
1397+
for v in value.values:
1398+
if v.valueKind == 'known' and v.intvalue >= limit:
1399+
if not 'U' in value.str.upper():
1400+
self.reportError(value, 7, 2)
1401+
1402+
for token in data.tokenlist:
1403+
# Check normal variable assignment
1404+
if token.valueType and token.isNumber:
1405+
variable = getAssignedVariableToken(token)
1406+
reportErrorIfMissingSuffix(variable, token)
1407+
1408+
# Check use as function parameter
1409+
if isFunctionCall(token) and token.astOperand1 and token.astOperand1.function:
1410+
functionDeclaration = token.astOperand1.function
1411+
1412+
if functionDeclaration.tokenDef:
1413+
if functionDeclaration.tokenDef.Id == token.astOperand1.Id:
1414+
# Token is not a function call, but it is the definition of the function
1415+
continue
1416+
1417+
parametersUsed = getArguments(token)
1418+
for i in range(len(parametersUsed)):
1419+
usedParameter = parametersUsed[i]
1420+
if usedParameter.isNumber:
1421+
parameterDefinition = functionDeclaration.argument.get(i+1)
1422+
reportErrorIfMissingSuffix(parameterDefinition.nameToken, usedParameter)
1423+
13901424
def misra_7_3(self, rawTokens):
13911425
compiled = re.compile(r'^[0-9.uU]+l')
13921426
for tok in rawTokens:
@@ -1418,13 +1452,13 @@ def reportErrorIfVariableIsNotConst(variable, stringLiteral):
14181452
# Check use as function parameter
14191453
if isFunctionCall(token) and token.astOperand1 and token.astOperand1.function:
14201454
functionDeclaration = token.astOperand1.function
1421-
parametersUsed = getArguments(token)
1422-
1423-
if functionDeclaration and functionDeclaration.tokenDef:
1455+
1456+
if functionDeclaration.tokenDef:
14241457
if functionDeclaration.tokenDef.Id == token.astOperand1.Id:
14251458
# Token is not a function call, but it is the definition of the function
14261459
continue
14271460

1461+
parametersUsed = getArguments(token)
14281462
for i in range(len(parametersUsed)):
14291463
usedParameter = parametersUsed[i]
14301464
parameterDefinition = functionDeclaration.argument.get(i+1)
@@ -3036,6 +3070,8 @@ def parseDump(self, dumpfile):
30363070
self.executeCheck(602, self.misra_6_2, cfg)
30373071
if cfgNumber == 0:
30383072
self.executeCheck(701, self.misra_7_1, data.rawTokens)
3073+
self.executeCheck(702, self.misra_7_2, cfg)
3074+
if cfgNumber == 0:
30393075
self.executeCheck(703, self.misra_7_3, data.rawTokens)
30403076
self.executeCheck(704, self.misra_7_4, cfg)
30413077
self.executeCheck(811, self.misra_8_11, cfg)

addons/test/misra/misra-test.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,30 @@ void misra_7_1() {
225225
int x = 066; // 7.1
226226
}
227227

228+
void misra_7_2_call_test(int a, unsigned int b, unsigned int c) { } // 2.7
229+
230+
void misra_7_2() {
231+
unsigned int a = 2147483647;
232+
const unsigned int b = 2147483648U;
233+
const unsigned int c = 2147483648; // 7.2
234+
unsigned int d = 2147483649; // 7.2
235+
236+
unsigned char e = 0x80; // 7.2
237+
unsigned char f = 0x80U;
238+
unsigned short g = 0x8000; // 7.2
239+
unsigned short h = 0x8000U;
240+
unsigned int i = 0x80000000; // 7.2
241+
unsigned int j = 0x80000000U;
242+
unsigned long long k = 0x8000000000000000; // 7.2
243+
unsigned long long l = 0x8000000000000000ULL;
244+
245+
unsigned int m = 1 + 0x80000000; // 7.2 10.4
246+
247+
misra_7_2_call_test(1, 2, 2147483648U);
248+
misra_7_2_call_test(1, 2, 2147483648); // 7.2
249+
misra_7_2_call_test(1, 0x80000000, 3); // 7.2
250+
}
251+
228252
void misra_7_3() {
229253
long misra_7_3_a = 0l; //7.3
230254
long misra_7_3_b = 0lU; //7.3

0 commit comments

Comments
 (0)