misra; implement rule 2.3
This commit is contained in:
parent
00a9671f46
commit
13d55c7060
|
@ -571,12 +571,14 @@ class TypedefInfo:
|
||||||
name = None
|
name = None
|
||||||
filename = None
|
filename = None
|
||||||
lineNumber = None
|
lineNumber = None
|
||||||
|
column = None
|
||||||
used = None
|
used = None
|
||||||
|
|
||||||
def __init__(self, element):
|
def __init__(self, element):
|
||||||
self.name = element.get('name')
|
self.name = element.get('name')
|
||||||
self.filename = element.get('file')
|
self.filename = element.get('file')
|
||||||
self.lineNumber = int(element.get('line'))
|
self.lineNumber = int(element.get('line'))
|
||||||
|
self.column = int(element.get('column'))
|
||||||
self.used = (element.get('used') == '1')
|
self.used = (element.get('used') == '1')
|
||||||
|
|
||||||
class Value:
|
class Value:
|
||||||
|
|
|
@ -1103,6 +1103,8 @@ class MisraChecker:
|
||||||
|
|
||||||
self.existing_violations = set()
|
self.existing_violations = set()
|
||||||
|
|
||||||
|
self._ctu_summary_typedefs = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
attrs = ["settings", "verify_expected", "verify_actual", "violations",
|
attrs = ["settings", "verify_expected", "verify_actual", "violations",
|
||||||
"ruleTexts", "suppressedRules", "filePrefix",
|
"ruleTexts", "suppressedRules", "filePrefix",
|
||||||
|
@ -1118,6 +1120,23 @@ class MisraChecker:
|
||||||
else:
|
else:
|
||||||
return 63
|
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):
|
def misra_2_7(self, data):
|
||||||
for func in data.functions:
|
for func in data.functions:
|
||||||
# Skip function with no parameter
|
# Skip function with no parameter
|
||||||
|
@ -1342,11 +1361,8 @@ class MisraChecker:
|
||||||
def misra_5_6(self, data):
|
def misra_5_6(self, data):
|
||||||
dumpfile = data[0]
|
dumpfile = data[0]
|
||||||
typedefInfo = data[1]
|
typedefInfo = data[1]
|
||||||
summary = []
|
self._save_ctu_summary_typedefs(dumpfile, typedefInfo)
|
||||||
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)
|
|
||||||
|
|
||||||
def misra_6_1(self, data):
|
def misra_6_1(self, data):
|
||||||
# Bitfield type must be bool or explicitly signed/unsigned int
|
# Bitfield type must be bool or explicitly signed/unsigned int
|
||||||
|
@ -3256,6 +3272,7 @@ class MisraChecker:
|
||||||
if not self.settings.quiet:
|
if not self.settings.quiet:
|
||||||
self.printStatus('Checking %s, config %s...' % (dumpfile, cfg.name))
|
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)
|
self.executeCheck(207, self.misra_2_7, cfg)
|
||||||
# data.rawTokens is same for all configurations
|
# data.rawTokens is same for all configurations
|
||||||
if cfgNumber == 0:
|
if cfgNumber == 0:
|
||||||
|
@ -3362,7 +3379,7 @@ class MisraChecker:
|
||||||
# 22.4 is already covered by Cppcheck writeReadOnlyFile
|
# 22.4 is already covered by Cppcheck writeReadOnlyFile
|
||||||
|
|
||||||
def analyse_ctu_info(self, files):
|
def analyse_ctu_info(self, files):
|
||||||
data_misra_5_6 = []
|
all_typedef_info = []
|
||||||
|
|
||||||
Location = namedtuple('Location', 'file linenr column')
|
Location = namedtuple('Location', 'file linenr column')
|
||||||
|
|
||||||
|
@ -3370,23 +3387,33 @@ class MisraChecker:
|
||||||
if not filename.endswith('.ctu-info'):
|
if not filename.endswith('.ctu-info'):
|
||||||
continue
|
continue
|
||||||
for line in open(filename, 'rt'):
|
for line in open(filename, 'rt'):
|
||||||
if line.startswith('{'):
|
if not line.startswith('{'):
|
||||||
s = json.loads(line)
|
continue
|
||||||
summary_type = s['summary']
|
|
||||||
summary_data = s['data']
|
|
||||||
|
|
||||||
# TODO break out info some function
|
s = json.loads(line)
|
||||||
if summary_type == 'misra_5_6':
|
summary_type = s['summary']
|
||||||
for info1 in summary_data:
|
summary_data = s['data']
|
||||||
found = False
|
|
||||||
for info2 in data_misra_5_6:
|
# TODO break out info some function
|
||||||
if info1['name'] == info2['name']:
|
if summary_type != 'MisraTypedefInfo':
|
||||||
found = True
|
continue
|
||||||
if info1['file'] != info2['file'] or info1['line'] != info2['line']:
|
for new_typedef_info in summary_data:
|
||||||
self.reportError(Location(info2['file'], info2['line'], 0), 5, 6)
|
found = False
|
||||||
self.reportError(Location(info1['file'], info1['line'], 0), 5, 6)
|
for old_typedef_info in all_typedef_info:
|
||||||
if not found:
|
if old_typedef_info['name'] == new_typedef_info['name']:
|
||||||
data_misra_5_6.append(info1)
|
found = True
|
||||||
|
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:
|
||||||
|
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
|
RULE_TEXTS_HELP = '''Path to text file of MISRA rules
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#include "misra-ctu-test.h"
|
#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
|
// cppcheck-suppress misra-c2012-5.6
|
||||||
typedef int MISRA_5_6_VIOLATION;
|
typedef int MISRA_5_6_VIOLATION;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#include "misra-ctu-test.h"
|
#include "misra-ctu-test.h"
|
||||||
|
|
||||||
|
MISRA_2_3_B misra_2_3_b;
|
||||||
|
|
||||||
// cppcheck-suppress misra-c2012-5.6
|
// cppcheck-suppress misra-c2012-5.6
|
||||||
typedef int MISRA_5_6_VIOLATION;
|
typedef int MISRA_5_6_VIOLATION;
|
||||||
|
static MISRA_5_6_VIOLATION misra_5_6_x;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1048,6 +1048,7 @@ void Tokenizer::simplifyTypedef()
|
||||||
typedefInfo.name = typeName->str();
|
typedefInfo.name = typeName->str();
|
||||||
typedefInfo.filename = list.file(typeName);
|
typedefInfo.filename = list.file(typeName);
|
||||||
typedefInfo.lineNumber = typeName->linenr();
|
typedefInfo.lineNumber = typeName->linenr();
|
||||||
|
typedefInfo.column = typeName->column();
|
||||||
typedefInfo.used = false;
|
typedefInfo.used = false;
|
||||||
mTypedefInfo.push_back(typedefInfo);
|
mTypedefInfo.push_back(typedefInfo);
|
||||||
|
|
||||||
|
@ -5499,6 +5500,7 @@ void Tokenizer::dump(std::ostream &out) const
|
||||||
<< " name=\"" << typedefInfo.name << "\""
|
<< " name=\"" << typedefInfo.name << "\""
|
||||||
<< " file=\"" << typedefInfo.filename << "\""
|
<< " file=\"" << typedefInfo.filename << "\""
|
||||||
<< " line=\"" << typedefInfo.lineNumber << "\""
|
<< " line=\"" << typedefInfo.lineNumber << "\""
|
||||||
|
<< " column=\"" << typedefInfo.column << "\""
|
||||||
<< " used=\"" << (typedefInfo.used?1:0) << "\""
|
<< " used=\"" << (typedefInfo.used?1:0) << "\""
|
||||||
<< "/>" << std::endl;
|
<< "/>" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -991,6 +991,7 @@ private:
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
int lineNumber;
|
int lineNumber;
|
||||||
|
int column;
|
||||||
bool used;
|
bool used;
|
||||||
};
|
};
|
||||||
std::vector<TypedefInfo> mTypedefInfo;
|
std::vector<TypedefInfo> mTypedefInfo;
|
||||||
|
|
Loading…
Reference in New Issue