misra; implement rule 8.7

This commit is contained in:
Daniel Marjamäki 2021-07-17 22:36:03 +02:00
parent 77d8b714ea
commit f44a82856f
6 changed files with 59 additions and 5 deletions

View File

@ -45,5 +45,5 @@ jobs:
C:\tools\cygwin\bin\bash.exe -l -c cd %GITHUB_WORKSPACE%\addons\test
..\..\cppcheck --dump --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 && python3 ..\misra.py -verify misra\misra-test.c.dump
C:\tools\cygwin\bin\bash.exe -l -c cd %GITHUB_WORKSPACE%
.\cppcheck --addon=misra --inline-suppr --error-exitcode=1 addons\test\misra\misra-ctu-*-test.c
.\cppcheck --addon=misra --inline-suppr --enable=information --error-exitcode=1 addons\test\misra\misra-ctu-*-test.c

View File

@ -125,7 +125,7 @@ jobs:
run: |
./cppcheck --addon=threadsafety addons/test/threadsafety
./cppcheck --addon=threadsafety --std=c++03 addons/test/threadsafety
./cppcheck --addon=misra --inline-suppr --error-exitcode=1 addons/test/misra/misra-ctu-*-test.c
./cppcheck --addon=misra --inline-suppr --enable=information --error-exitcode=1 addons/test/misra/misra-ctu-*-test.c
cd addons/test
../../cppcheck --dump --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 && python3 ../misra.py -verify misra/misra-test.c.dump

View File

@ -135,7 +135,7 @@ jobs:
- name: Test addons
run: |
.\cppcheck.exe --addon=misra --inline-suppr --error-exitcode=1 addons\test\misra\misra-ctu-*-test.c
.\cppcheck.exe --addon=misra --inline-suppr --enable=information --error-exitcode=1 addons\test\misra\misra-ctu-*-test.c
cd addons\test
..\..\cppcheck.exe --dump --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 && python3 ..\misra.py -verify misra\misra-test.c.dump

View File

@ -1161,6 +1161,7 @@ class MisraChecker:
self._ctu_summary_typedefs = False
self._ctu_summary_tagnames = False
self._ctu_summary_identifiers = False
self._ctu_summary_usage = False
def __repr__(self):
attrs = ["settings", "verify_expected", "verify_actual", "violations",
@ -1258,6 +1259,28 @@ class MisraChecker:
cppcheckdata.reportSummary(dumpfile, 'MisraInternalIdentifiers', internal_identifiers)
cppcheckdata.reportSummary(dumpfile, 'MisraLocalIdentifiers', local_identifiers)
def _save_ctu_summary_usage(self, dumpfile, cfg):
if self._ctu_summary_usage:
return
self._ctu_summary_usage = True
names = []
for token in cfg.tokenlist:
if not token.isName:
continue
if token.function and token.scope.isExecutable:
if (not token.function.isStatic) and (token.str not in names):
names.append(token.str)
elif token.variable:
if token == token.variable.nameToken:
continue
if token.variable.access == 'Global' and (not token.variable.isStatic) and (token.str not in names):
names.append(token.str)
if len(names) > 0:
cppcheckdata.reportSummary(dumpfile, 'MisraUsage', names)
def misra_2_3(self, dumpfile, typedefInfo):
self._save_ctu_summary_typedefs(dumpfile, typedefInfo)
@ -1803,6 +1826,15 @@ class MisraChecker:
if var.isExtern and var.nameToken and not is_header(var.nameToken.file):
self.reportError(var.nameToken, 8, 4)
def misra_8_5(self, dumpfile, cfg):
self._save_ctu_summary_identifiers(dumpfile, cfg)
def misra_8_6(self, dumpfile, cfg):
self._save_ctu_summary_identifiers(dumpfile, cfg)
def misra_8_7(self, dumpfile, cfg):
self._save_ctu_summary_usage(dumpfile, cfg)
def misra_8_11(self, data):
for var in data.variables:
if var.isExtern and simpleMatch(var.nameToken.next, '[ ]') and var.nameToken.scope.type == 'Global':
@ -3520,6 +3552,9 @@ class MisraChecker:
if cfgNumber == 0:
self.executeCheck(802, self.misra_8_2, cfg, data.rawTokens)
self.executeCheck(804, self.misra_8_4, cfg)
self.executeCheck(805, self.misra_8_5, dumpfile, cfg)
self.executeCheck(806, self.misra_8_6, dumpfile, cfg)
self.executeCheck(807, self.misra_8_7, dumpfile, cfg)
self.executeCheck(811, self.misra_8_11, cfg)
self.executeCheck(812, self.misra_8_12, cfg)
if cfgNumber == 0:
@ -3613,6 +3648,7 @@ class MisraChecker:
all_external_identifiers_def = {}
all_internal_identifiers = {}
all_local_identifiers = {}
all_usage_count = {}
from cppcheckdata import Location
@ -3698,6 +3734,13 @@ class MisraChecker:
for s in summary_data:
all_local_identifiers[s['name']] = s
if summary_type == 'MisraUsage':
for s in summary_data:
if s in all_usage_count:
all_usage_count[s] += 1
else:
all_usage_count[s] = 1
for ti in all_typedef_info:
if not ti['used']:
self.reportError(Location(ti), 2, 3)
@ -3723,6 +3766,12 @@ class MisraChecker:
self.reportError(Location(local_identifier), 5, 8)
self.reportError(Location(external_identifier), 5, 8)
for name, count in all_usage_count.items():
#print('%s:%i' % (name, count))
if count != 1:
continue
if name in all_external_identifiers:
self.reportError(Location(all_external_identifiers[name]), 8, 7)
RULE_TEXTS_HELP = '''Path to text file of MISRA rules

View File

@ -1,5 +1,5 @@
// Test with command:
// ./cppcheck --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c
// ./cppcheck --enable=information --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c
#include "misra-ctu-test.h"

View File

@ -1,5 +1,5 @@
// Test with command:
// ./cppcheck --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c
// ./cppcheck --enable=information --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c
#include "misra-ctu-test.h"
@ -38,3 +38,8 @@ extern int misra_8_5;
// cppcheck-suppress misra-c2012-8.6
int32_t misra_8_6 = 2;
// cppcheck-suppress misra-c2012-8.4
// cppcheck-suppress misra-c2012-8.7
void misra_8_7(void) {}
static void misra_8_7_caller(void) { misra_8_7(); }