misra: Fix crash in misra_9x when there is unknown constant used as array size (#5229)

This commit is contained in:
Daniel Marjamäki 2023-07-10 12:25:28 +02:00 committed by GitHub
parent 276aace331
commit 2cd1f0f387
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 5 deletions

View File

@ -392,7 +392,7 @@ jobs:
run: | run: |
./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety addons/test/threadsafety ./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety addons/test/threadsafety
./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety --std=c++03 addons/test/threadsafety ./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety --std=c++03 addons/test/threadsafety
./cppcheck --error-exitcode=1 --addon=misra addons/test/misra/crash*.c ./cppcheck --error-exitcode=1 --inline-suppr --addon=misra addons/test/misra/crash*.c
./cppcheck --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 addons/test/misra/misra-ctu-*-test.c ./cppcheck --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 addons/test/misra/misra-ctu-*-test.c
pushd addons/test pushd addons/test
# We'll force C89 standard to enable an additional verification for # We'll force C89 standard to enable an additional verification for

View File

@ -1,3 +1,5 @@
import cppcheckdata
# Holds information about an array, struct or union's element definition. # Holds information about an array, struct or union's element definition.
class ElementDef: class ElementDef:
def __init__(self, elementType, name, valueType, dimensions = None): def __init__(self, elementType, name, valueType, dimensions = None):
@ -381,6 +383,39 @@ 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', f'Unknown constant {t.str}, please review configuration', '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()
for variable in data.variables: for variable in data.variables:

View File

@ -4,6 +4,7 @@ struct ConDesDesc {
unsigned Import; unsigned Import;
}; };
// cppcheck-suppress misra-config
static ConDesDesc ConDes[CD_TYPE_COUNT] = { static ConDesDesc ConDes[CD_TYPE_COUNT] = {
{ 0, 0 }, { 0, 0 },
{ 0, 0 }, { 0, 0 },

View File

@ -0,0 +1,23 @@
struct _boardcnf_ch {
// cppcheck-suppress misra-config
uint8_t ddr_density[CS_CNT];
uint64_t ca_swap;
};
struct _boardcnf {
uint16_t dqdm_dly_r;
// cppcheck-suppress misra-config
struct _boardcnf_ch ch[DRAM_CH_CNT];
};
static const struct _boardcnf boardcnfs[1] = {
{
0x0a0,
{
{ {0x02, 0x02}, 0x00345201 },
{ {0x02, 0x02}, 0x00302154 }
}
},
};

View File

@ -586,10 +586,6 @@ static void misra_9_struct_initializers(void) {
struct1 os1 = { i1: 1, i2: 2 }; // 10.4 13.4 struct1 os1 = { i1: 1, i2: 2 }; // 10.4 13.4
} }
static void misra_9_broken_initializers(void) {
char a[UNKNOWN_MACRO] = { 19, 23, 0 }; // 18.8
}
static void misra_9_2(void) { static void misra_9_2(void) {
union misra_9_2_union { // 19.2 union misra_9_2_union { // 19.2
char c; char c;