diff --git a/addons/misra.py b/addons/misra.py index 8413ed794..88dd95af9 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -3259,23 +3259,26 @@ class MisraChecker: def misra_config(self, data): for token in data.tokenlist: - if token.str not in ["while", "if"]: - continue - if token.next.str != "(": + if token.str not in ("while", "if"): continue tok = token.next - while tok != token.next.link: + if token is None or tok.str != "(": + continue + end_token = tok.link + while tok != end_token: + tok = tok.next if tok.str == "(" and tok.isCast: tok = tok.link continue - if not tok.isName or tok.function or tok.variable or tok.varId or tok.valueType \ - or tok.next.str == "(" or tok.str in ["EOF"] \ - or isKeyword(tok.str) or isStdLibId(tok.str): - tok = tok.next + if not tok.isName: continue - errmsg = tok.str + " Variable is unknown" - self.reportError(token, 0, 0, "config") - break + if tok.function or tok.variable or tok.varId or tok.valueType: + continue + if tok.next.str == "(" or tok.str in ["EOF"]: + continue + if isKeyword(tok.str) or isStdLibId(tok.str): + continue + self.report_config_error(tok, "Variable '%s' is unknown" % tok.str) def misra_17_6(self, rawTokens): for token in rawTokens: @@ -4184,30 +4187,29 @@ class MisraChecker: self.addSuppressedRule(ruleNum) - def reportError(self, location, num1, num2, other_id = None): - if not other_id: - ruleNum = num1 * 100 + num2 + def report_config_error(self, location, errmsg): + cppcheck_severity = 'error' + error_id = 'config' + if self.settings.verify: + self.verify_actual.append('%s:%d %s' % (location.file, location.linenr, error_id)) else: - ruleNum = other_id + cppcheckdata.reportError(location, cppcheck_severity, errmsg, 'misra', error_id) + + def reportError(self, location, num1, num2): + ruleNum = num1 * 100 + num2 if self.isRuleGloballySuppressed(ruleNum): return if self.settings.verify: - if not other_id: - self.verify_actual.append('%s:%d %d.%d' % (location.file, location.linenr, num1, num2)) - else: - self.verify_actual.append('%s:%d %s' % (location.file, location.linenr, other_id)) + self.verify_actual.append('%s:%d %d.%d' % (location.file, location.linenr, num1, num2)) elif self.isRuleSuppressed(location.file, location.linenr, ruleNum): # Error is suppressed. Ignore self.suppressionStats.setdefault(ruleNum, 0) self.suppressionStats[ruleNum] += 1 return else: - if not other_id: - errorId = 'c2012-' + str(num1) + '.' + str(num2) - else: - errorId = 'c2012-' + other_id + errorId = 'c2012-' + str(num1) + '.' + str(num2) misra_severity = 'Undefined' cppcheck_severity = 'style' if ruleNum in self.ruleTexts: diff --git a/addons/test/test-misra.py b/addons/test/test-misra.py index 3701dc2f4..debd4f2a6 100644 --- a/addons/test/test-misra.py +++ b/addons/test/test-misra.py @@ -17,6 +17,14 @@ from .util import dump_create, dump_remove, convert_json_output TEST_SOURCE_FILES = ['./addons/test/misra/misra-test.c'] +def remove_misra_config(s:str): + ret = '' + for line in s.splitlines(): + if '[misra-config]' not in line: + ret += line + '\n' + return ret + + def setup_module(module): for f in TEST_SOURCE_FILES: dump_create(f) @@ -92,7 +100,7 @@ def test_rules_cppcheck_severity(checker, capsys): checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt") checker.parseDump("./addons/test/misra/misra-test.c.dump") captured = capsys.readouterr().err - assert("(error)" not in captured) + assert("(error)" not in remove_misra_config(captured)) assert("(warning)" not in captured) assert("(style)" in captured) @@ -101,7 +109,7 @@ def test_rules_cppcheck_severity_custom(checker, capsys): checker.setSeverity("custom-severity") checker.parseDump("./addons/test/misra/misra-test.c.dump") captured = capsys.readouterr().err - assert("(error)" not in captured) + assert("(error)" not in remove_misra_config(captured)) assert("(warning)" not in captured) assert("(style)" not in captured) assert("(custom-severity)" in captured) diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 41b73f9cb..886ebd516 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -45,6 +45,7 @@ const std::set ErrorLogger::mCriticalErrorIds{ "internalAstError", "instantiationError", "internalError", + "misra-config", "premium-internalError", "premium-invalidArgument", "premium-invalidLicense",