Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion addons/misra.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,14 @@ def isConstantExpression(expr):
return False
return True

def isUnknownConstantExpression(expr):
if expr.isName and not isEnumConstant(expr) and expr.variable is None:
return True
if expr.astOperand1 and isUnknownConstantExpression(expr.astOperand1):
return True
if expr.astOperand2 and isUnknownConstantExpression(expr.astOperand2):
return True
return False

def isUnsignedInt(expr):
return expr and expr.valueType and expr.valueType.type in ('short', 'int') and expr.valueType.sign == 'unsigned'
Expand Down Expand Up @@ -3258,6 +3266,32 @@ def misra_17_3(self, cfg):
tok = tok.next

def misra_config(self, data):
for var in data.variables:
if not var.isArray or var.nameToken is None or not cppcheckdata.simpleMatch(var.nameToken.next, '['):
continue
tok = var.nameToken.next
while tok.str == '[':
sz = tok.astOperand2
if sz and sz.getKnownIntValue() is None:
has_var = False
unknown_constant = False
tokens = [sz]
while len(tokens) > 0:
t = tokens[-1]
tokens = tokens[:-1]
if t:
if t.isName and t.getKnownIntValue() is None:
if t.varId or t.variable:
has_var = True
continue
unknown_constant = True
self.report_config_error(tok, 'Unknown constant {}, please review configuration'.format(t.str))
if t.isArithmeticalOp:
tokens += [t.astOperand1, t.astOperand2]
if not unknown_constant and not has_var:
self.report_config_error(tok, 'Unknown array size, please review configuration')
tok = tok.link.next

for token in data.tokenlist:
if token.str not in ("while", "if"):
continue
Expand Down Expand Up @@ -3367,7 +3401,7 @@ def misra_18_8(self, data):
# Unknown define or syntax error
if not typetok.astOperand2:
continue
if not isConstantExpression(typetok.astOperand2):
if not isConstantExpression(typetok.astOperand2) and not isUnknownConstantExpression(typetok.astOperand2):
self.reportError(var.nameToken, 18, 8)

def misra_19_2(self, data):
Expand Down
32 changes: 0 additions & 32 deletions addons/misra_9.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,38 +396,6 @@ def unwindAndContinue(self):
break

def misra_9_x(self, data, rule, rawTokens = None):
# If there are arrays with unknown size constants then we need to warn about missing configuration
# and bailout
has_config_errors = False
for var in data.variables:
if not var.isArray or var.nameToken is None or not cppcheckdata.simpleMatch(var.nameToken.next,'['):
continue
tok = var.nameToken.next
while tok.str == '[':
sz = tok.astOperand2
if sz and sz.getKnownIntValue() is None:
has_var = False
unknown_constant = False
tokens = [sz]
while len(tokens) > 0:
t = tokens[-1]
tokens = tokens[:-1]
if t:
if t.isName and t.getKnownIntValue() is None:
if t.varId or t.variable:
has_var = True
continue
unknown_constant = True
cppcheckdata.reportError(sz, 'error', 'Unknown constant {}, please review configuration'.format(t.str), 'misra', 'config')
has_config_errors = True
if t.isArithmeticalOp:
tokens += [t.astOperand1, t.astOperand2]
if not unknown_constant and not has_var:
cppcheckdata.reportError(sz, 'error', 'Unknown array size, please review configuration', 'misra', 'config')
has_config_errors = True
tok = tok.link.next
if has_config_errors:
return

parser = InitializerParser()

Expand Down
2 changes: 2 additions & 0 deletions addons/test/misra/misra-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,8 @@ static void misra_18_8(int x) {
int buf1[10];
int buf2[sizeof(int)];
int vla[x]; // 18.8
// #9498
int vlb[y]; // config
static const unsigned char arr18_8_1[] = UNDEFINED_ID;
static uint32_t enum_test_0[R18_8_ENUM_CONSTANT_0] = {0};
}
Expand Down