parent
083c4aa34b
commit
56bfa9f3ea
|
@ -897,6 +897,14 @@ def isConstantExpression(expr):
|
||||||
return False
|
return False
|
||||||
return True
|
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):
|
def isUnsignedInt(expr):
|
||||||
return expr and expr.valueType and expr.valueType.type in ('short', 'int') and expr.valueType.sign == 'unsigned'
|
return expr and expr.valueType and expr.valueType.type in ('short', 'int') and expr.valueType.sign == 'unsigned'
|
||||||
|
@ -3258,6 +3266,32 @@ class MisraChecker:
|
||||||
tok = tok.next
|
tok = tok.next
|
||||||
|
|
||||||
def misra_config(self, data):
|
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:
|
for token in data.tokenlist:
|
||||||
if token.str not in ("while", "if"):
|
if token.str not in ("while", "if"):
|
||||||
continue
|
continue
|
||||||
|
@ -3367,7 +3401,7 @@ class MisraChecker:
|
||||||
# Unknown define or syntax error
|
# Unknown define or syntax error
|
||||||
if not typetok.astOperand2:
|
if not typetok.astOperand2:
|
||||||
continue
|
continue
|
||||||
if not isConstantExpression(typetok.astOperand2):
|
if not isConstantExpression(typetok.astOperand2) and not isUnknownConstantExpression(typetok.astOperand2):
|
||||||
self.reportError(var.nameToken, 18, 8)
|
self.reportError(var.nameToken, 18, 8)
|
||||||
|
|
||||||
def misra_19_2(self, data):
|
def misra_19_2(self, data):
|
||||||
|
|
|
@ -396,38 +396,6 @@ class InitializerParser:
|
||||||
break
|
break
|
||||||
|
|
||||||
def misra_9_x(self, data, rule, rawTokens = None):
|
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()
|
parser = InitializerParser()
|
||||||
|
|
||||||
|
|
|
@ -1783,6 +1783,8 @@ static void misra_18_8(int x) {
|
||||||
int buf1[10];
|
int buf1[10];
|
||||||
int buf2[sizeof(int)];
|
int buf2[sizeof(int)];
|
||||||
int vla[x]; // 18.8
|
int vla[x]; // 18.8
|
||||||
|
// #9498
|
||||||
|
int vlb[y]; // config
|
||||||
static const unsigned char arr18_8_1[] = UNDEFINED_ID;
|
static const unsigned char arr18_8_1[] = UNDEFINED_ID;
|
||||||
static uint32_t enum_test_0[R18_8_ENUM_CONSTANT_0] = {0};
|
static uint32_t enum_test_0[R18_8_ENUM_CONSTANT_0] = {0};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue