misra.py: Fix large memory usage with suppressions (#2321)

* misra.py: Fix large memory usage with suppressions

Don't save whole lxml locations when collecting rules suppressions
statistics. This fixes the problem with large memory usage when
some rules are suppressed.

See issue description:
https://sourceforge.net/p/cppcheck/discussion/development/thread/51fc053626/

* don't override 'file' builtin
This commit is contained in:
Georgy Komarov 2019-11-04 08:58:33 +03:00 committed by Daniel Marjamäki
parent ff61d8e370
commit c207828a11
1 changed files with 13 additions and 12 deletions

View File

@ -727,7 +727,7 @@ class MisraChecker:
# Prefix to ignore when matching suppression files. # Prefix to ignore when matching suppression files.
self.filePrefix = None self.filePrefix = None
# Statistics of all violations suppressed per rule # Number of all violations suppressed per rule
self.suppressionStats = dict() self.suppressionStats = dict()
self.stdversion = stdversion self.stdversion = stdversion
@ -2154,10 +2154,13 @@ class MisraChecker:
ruleItemList.append(line_symbol) ruleItemList.append(line_symbol)
def isRuleSuppressed(self, location, ruleNum): def isRuleSuppressed(self, file_path, linenr, ruleNum):
""" """
Check to see if a rule is suppressed. Check to see if a rule is suppressed.
ruleNum is the rule number in hundreds format
:param ruleNum: is the rule number in hundreds format
:param file_path: File path of checked location
:param linenr: Line number of checked location
If the rule exists in the dict then check for a filename If the rule exists in the dict then check for a filename
If the filename is None then rule is suppressed globally If the filename is None then rule is suppressed globally
@ -2172,15 +2175,14 @@ class MisraChecker:
""" """
ruleIsSuppressed = False ruleIsSuppressed = False
linenr = location.linenr
# Remove any prefix listed in command arguments from the filename. # Remove any prefix listed in command arguments from the filename.
filename = None filename = None
if location.file is not None: if file_path is not None:
if self.filePrefix is not None: if self.filePrefix is not None:
filename = remove_file_prefix(location.file, self.filePrefix) filename = remove_file_prefix(file_path, self.filePrefix)
else: else:
filename = os.path.basename(location.file) filename = os.path.basename(file_path)
if ruleNum in self.suppressedRules: if ruleNum in self.suppressedRules:
fileDict = self.suppressedRules[ruleNum] fileDict = self.suppressedRules[ruleNum]
@ -2263,7 +2265,7 @@ class MisraChecker:
else: else:
item_str = str(item[0]) item_str = str(item[0])
outlist.append("%s: %s: %s (%d locations suppressed)" % (float(ruleNum)/100,fname,item_str, len(self.suppressionStats.get(ruleNum, [])))) outlist.append("%s: %s: %s (%d locations suppressed)" % (float(ruleNum)/100,fname,item_str, self.suppressionStats.get(ruleNum, 0)))
for line in sorted(outlist, reverse=True): for line in sorted(outlist, reverse=True):
print(" %s" % line) print(" %s" % line)
@ -2297,11 +2299,10 @@ class MisraChecker:
if self.settings.verify: if self.settings.verify:
self.verify_actual.append(str(location.linenr) + ':' + str(num1) + '.' + str(num2)) self.verify_actual.append(str(location.linenr) + ':' + str(num1) + '.' + str(num2))
elif self.isRuleSuppressed(location, ruleNum): elif self.isRuleSuppressed(location.file, location.linenr, ruleNum):
# Error is suppressed. Ignore # Error is suppressed. Ignore
if not ruleNum in self.suppressionStats: self.suppressionStats.setdefault(ruleNum, 0)
self.suppressionStats[ruleNum] = [] self.suppressionStats[ruleNum] += 1
self.suppressionStats[ruleNum].append(location)
return return
else: else:
errorId = 'c2012-' + str(num1) + '.' + str(num2) errorId = 'c2012-' + str(num1) + '.' + str(num2)