misra; implement rule 2.3

This commit is contained in:
Daniel Marjamäki 2021-07-07 15:16:53 +02:00
parent 00a9671f46
commit 13d55c7060
7 changed files with 66 additions and 25 deletions

View File

@ -571,12 +571,14 @@ class TypedefInfo:
name = None
filename = None
lineNumber = None
column = None
used = None
def __init__(self, element):
self.name = element.get('name')
self.filename = element.get('file')
self.lineNumber = int(element.get('line'))
self.column = int(element.get('column'))
self.used = (element.get('used') == '1')
class Value:

View File

@ -1103,6 +1103,8 @@ class MisraChecker:
self.existing_violations = set()
self._ctu_summary_typedefs = False
def __repr__(self):
attrs = ["settings", "verify_expected", "verify_actual", "violations",
"ruleTexts", "suppressedRules", "filePrefix",
@ -1118,6 +1120,23 @@ class MisraChecker:
else:
return 63
def _save_ctu_summary_typedefs(self, dumpfile, typedef_info):
if self._ctu_summary_typedefs:
return
self._ctu_summary_typedefs = True
summary = []
for ti in typedef_info:
summary.append({ 'name': ti.name, 'file': ti.filename, 'line': ti.lineNumber, 'column': ti.column, 'used': ti.used })
if len(summary) > 0:
cppcheckdata.reportSummary(dumpfile, 'MisraTypedefInfo', summary)
def misra_2_3(self, data):
dumpfile = data[0]
typedefInfo = data[1]
self._save_ctu_summary_typedefs(dumpfile, typedefInfo)
def misra_2_7(self, data):
for func in data.functions:
# Skip function with no parameter
@ -1342,11 +1361,8 @@ class MisraChecker:
def misra_5_6(self, data):
dumpfile = data[0]
typedefInfo = data[1]
summary = []
for ti in typedefInfo:
summary.append({ 'name': ti.name, 'file': ti.filename, 'line': ti.lineNumber })
if len(summary) > 0:
cppcheckdata.reportSummary(dumpfile, 'misra_5_6', summary)
self._save_ctu_summary_typedefs(dumpfile, typedefInfo)
def misra_6_1(self, data):
# Bitfield type must be bool or explicitly signed/unsigned int
@ -3256,6 +3272,7 @@ class MisraChecker:
if not self.settings.quiet:
self.printStatus('Checking %s, config %s...' % (dumpfile, cfg.name))
self.executeCheck(203, self.misra_2_3, (dumpfile, cfg.typedefInfo))
self.executeCheck(207, self.misra_2_7, cfg)
# data.rawTokens is same for all configurations
if cfgNumber == 0:
@ -3362,7 +3379,7 @@ class MisraChecker:
# 22.4 is already covered by Cppcheck writeReadOnlyFile
def analyse_ctu_info(self, files):
data_misra_5_6 = []
all_typedef_info = []
Location = namedtuple('Location', 'file linenr column')
@ -3370,23 +3387,33 @@ class MisraChecker:
if not filename.endswith('.ctu-info'):
continue
for line in open(filename, 'rt'):
if line.startswith('{'):
if not line.startswith('{'):
continue
s = json.loads(line)
summary_type = s['summary']
summary_data = s['data']
# TODO break out info some function
if summary_type == 'misra_5_6':
for info1 in summary_data:
if summary_type != 'MisraTypedefInfo':
continue
for new_typedef_info in summary_data:
found = False
for info2 in data_misra_5_6:
if info1['name'] == info2['name']:
for old_typedef_info in all_typedef_info:
if old_typedef_info['name'] == new_typedef_info['name']:
found = True
if info1['file'] != info2['file'] or info1['line'] != info2['line']:
self.reportError(Location(info2['file'], info2['line'], 0), 5, 6)
self.reportError(Location(info1['file'], info1['line'], 0), 5, 6)
if old_typedef_info['file'] != new_typedef_info['file'] or old_typedef_info['line'] != new_typedef_info['line']:
self.reportError(Location(old_typedef_info['file'], old_typedef_info['line'], old_typedef_info['column']), 5, 6)
self.reportError(Location(new_typedef_info['file'], new_typedef_info['line'], new_typedef_info['column']), 5, 6)
else:
if new_typedef_info['used']:
old_typedef_info['used'] = True
if not found:
data_misra_5_6.append(info1)
all_typedef_info.append(new_typedef_info)
for ti in all_typedef_info:
if not ti['used']:
self.reportError(Location(ti['file'], ti['line'], ti['column']), 2, 3)
RULE_TEXTS_HELP = '''Path to text file of MISRA rules

View File

@ -3,6 +3,9 @@
#include "misra-ctu-test.h"
MISRA_2_3_A misra_2_3_a;
// cppcheck-suppress misra-c2012-2.3
// cppcheck-suppress misra-c2012-5.6
typedef int MISRA_5_6_VIOLATION;

View File

@ -3,6 +3,9 @@
#include "misra-ctu-test.h"
MISRA_2_3_B misra_2_3_b;
// cppcheck-suppress misra-c2012-5.6
typedef int MISRA_5_6_VIOLATION;
static MISRA_5_6_VIOLATION misra_5_6_x;

View File

@ -1,5 +1,8 @@
typedef int t1;
typedef int t2;
typedef int MISRA_2_3_A;
typedef int MISRA_2_3_B;
typedef int MISRA_2_3_VIOLATION; // cppcheck-suppress misra-c2012-2.3

View File

@ -1048,6 +1048,7 @@ void Tokenizer::simplifyTypedef()
typedefInfo.name = typeName->str();
typedefInfo.filename = list.file(typeName);
typedefInfo.lineNumber = typeName->linenr();
typedefInfo.column = typeName->column();
typedefInfo.used = false;
mTypedefInfo.push_back(typedefInfo);
@ -5499,6 +5500,7 @@ void Tokenizer::dump(std::ostream &out) const
<< " name=\"" << typedefInfo.name << "\""
<< " file=\"" << typedefInfo.filename << "\""
<< " line=\"" << typedefInfo.lineNumber << "\""
<< " column=\"" << typedefInfo.column << "\""
<< " used=\"" << (typedefInfo.used?1:0) << "\""
<< "/>" << std::endl;
}

View File

@ -991,6 +991,7 @@ private:
std::string name;
std::string filename;
int lineNumber;
int column;
bool used;
};
std::vector<TypedefInfo> mTypedefInfo;