From 2cd1f0f387abdfeb031a65c393eeae0b4d67d62b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 10 Jul 2023 12:25:28 +0200 Subject: [PATCH] misra: Fix crash in misra_9x when there is unknown constant used as array size (#5229) --- .github/workflows/CI-unixish.yml | 2 +- addons/misra_9.py | 35 ++++++++++++++++++++++++++++++++ addons/test/misra/crash4.c | 1 + addons/test/misra/crash5.c | 23 +++++++++++++++++++++ addons/test/misra/misra-test.c | 4 ---- 5 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 addons/test/misra/crash5.c diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index 62007c40b..902417375 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -392,7 +392,7 @@ jobs: run: | ./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 --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 pushd addons/test # We'll force C89 standard to enable an additional verification for diff --git a/addons/misra_9.py b/addons/misra_9.py index 3712d334c..d047f09a2 100644 --- a/addons/misra_9.py +++ b/addons/misra_9.py @@ -1,3 +1,5 @@ +import cppcheckdata + # Holds information about an array, struct or union's element definition. class ElementDef: def __init__(self, elementType, name, valueType, dimensions = None): @@ -381,6 +383,39 @@ class InitializerParser: 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', 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() for variable in data.variables: diff --git a/addons/test/misra/crash4.c b/addons/test/misra/crash4.c index fff093c56..786258184 100644 --- a/addons/test/misra/crash4.c +++ b/addons/test/misra/crash4.c @@ -4,6 +4,7 @@ struct ConDesDesc { unsigned Import; }; +// cppcheck-suppress misra-config static ConDesDesc ConDes[CD_TYPE_COUNT] = { { 0, 0 }, { 0, 0 }, diff --git a/addons/test/misra/crash5.c b/addons/test/misra/crash5.c new file mode 100644 index 000000000..860101539 --- /dev/null +++ b/addons/test/misra/crash5.c @@ -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 } + } + }, +}; diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index 846743392..2fd30c7e7 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -586,10 +586,6 @@ static void misra_9_struct_initializers(void) { 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) { union misra_9_2_union { // 19.2 char c;