Skip to content

Commit

Permalink
[analyzer] Add a new flag to demote missing checker errors to a warning
Browse files Browse the repository at this point in the history
Altough discouraged, if someone really insists on having a soft warning
when a checker is supplied to --enable or --disable, they can use the
new flag '--no-missing-checker-error', which is disabled by default.
  • Loading branch information
Szelethus committed Apr 5, 2023
1 parent 6f92895 commit 16d8425
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 12 deletions.
13 changes: 10 additions & 3 deletions analyzer/codechecker_analyzer/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,16 @@ def perform_analysis(args, skip_handlers, actions, metadata_tool,
missing_checkers = checkers.available(args.ordered_checkers,
available_checkers)
if missing_checkers:
LOG.error("No checker(s) with these names was found:\n%s",
'\n'.join(missing_checkers))
sys.exit(1)
diag_msg = "No checker(s) with these names was found:\n{}".format(
'\n'.join(missing_checkers))
if 'no_missing_checker_error' in args:
LOG.warning(diag_msg)
else:
LOG.error(diag_msg)
LOG.info("If you want to suppress errors relating to unknown "
"checker names, consider the option "
"'--no-missing-checker-error'")
sys.exit(1)

if 'stats_enabled' in args:
config_map[ClangSA.ANALYZER_NAME].set_checker_enabled(
Expand Down
9 changes: 9 additions & 0 deletions analyzer/codechecker_analyzer/cmd/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,15 @@ def add_arguments_to_parser(parser):
"the analysis. USE WISELY AND AT YOUR "
"OWN RISK!")

checkers_opts.add_argument('--no-missing-checker-error',
dest="no_missing_checker_error",
action='store_true',
required=False,
default=argparse.SUPPRESS,
help="Emit a warning instead of an error when "
"an unknown checker name is given to "
"either enable or disable.")

logger.add_verbose_arguments(parser)
parser.set_defaults(
func=main, func_process_config_file=cmd_config.process_config_file)
Expand Down
9 changes: 9 additions & 0 deletions analyzer/codechecker_analyzer/cmd/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,15 @@ def add_arguments_to_parser(parser):
"the analysis. USE WISELY AND AT YOUR "
"OWN RISK!")

checkers_opts.add_argument('--no-missing-checker-error',
dest="no_missing_checker_error",
action='store_true',
required=False,
default=argparse.SUPPRESS,
help="Emit a warning instead of an error when "
"an unknown checker name is given to "
"either enable or disable.")

output_opts = parser.add_argument_group("output arguments")

output_opts.add_argument('--print-steps',
Expand Down
79 changes: 70 additions & 9 deletions analyzer/tests/functional/analyze/test_analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,12 +764,12 @@ def test_compile_uniqueing(self):
self.assertFalse(os.path.isdir(failed_dir))
self.check_unique_compilation_db(unique_json, 3, True, True, True)

def test_invalid_enabled_checker_name(self):
"""Error out in case of an invalid enabled checker."""
def __run_with_invalid_enabled_checker_name(self, extra_args):
build_json = os.path.join(self.test_workspace, "build_success.json")
analyze_cmd = [self._codechecker_cmd, "analyze", build_json,
"--analyzers", "clangsa", "-o", self.report_dir,
"-e", "non-existing-checker-name"]
analyze_cmd.extend(extra_args)

source_file = os.path.join(self.test_dir, "success.c")
build_log = [{"directory": self.test_workspace,
Expand All @@ -781,6 +781,7 @@ def test_invalid_enabled_checker_name(self):
encoding="utf-8", errors="ignore") as outfile:
json.dump(build_log, outfile)

print(extra_args)
print(analyze_cmd)
process = subprocess.Popen(
analyze_cmd,
Expand All @@ -789,15 +790,33 @@ def test_invalid_enabled_checker_name(self):
cwd=self.test_dir,
encoding="utf-8",
errors="ignore")
out, _ = process.communicate()
out, err = process.communicate()
return out, err, process.returncode

def test_invalid_enabled_checker_name(self):
"""Error out in case of an invalid enabled checker."""
out, _, errcode = self.__run_with_invalid_enabled_checker_name([])

match = self.missing_checker_regex.search(out)
self.assertIsNotNone(match)
self.assertTrue("non-existing-checker-name" in out)

errcode = process.returncode
self.assertEqual(errcode, 1)

def test_invalid_enabled_checker_name_warn(self):
"""
Warn in case of an invalid enabled checker when using
--no-missing-checker-error.
"""
out, _, errcode = self.__run_with_invalid_enabled_checker_name(
['--no-missing-checker-error'])

match = self.missing_checker_regex.search(out)
self.assertIsNotNone(match)
self.assertTrue("non-existing-checker-name" in out)

self.assertEqual(errcode, 0)

def test_disable_all_warnings(self):
"""Test disabling warnings as checker groups."""
build_json = os.path.join(self.test_workspace, "build.json")
Expand Down Expand Up @@ -830,12 +849,12 @@ def test_disable_all_warnings(self):
self.assertIn("unused variable 'i' [clang-diagnostic-unused-variable]",
out)

def test_invalid_disabled_checker_name(self):
"""Error out in case of an invalid disabled checker."""
def __run_with_invalid_disabled_checker_name(self, extra_args):
build_json = os.path.join(self.test_workspace, "build_success.json")
analyze_cmd = [self._codechecker_cmd, "analyze", build_json,
"--analyzers", "clangsa", "-o", self.report_dir,
"-d", "non-existing-checker-name"]
analyze_cmd.extend(extra_args)

source_file = os.path.join(self.test_dir, "success.c")
build_log = [{"directory": self.test_workspace,
Expand All @@ -855,15 +874,33 @@ def test_invalid_disabled_checker_name(self):
cwd=self.test_dir,
encoding="utf-8",
errors="ignore")
out, _ = process.communicate()
out, err = process.communicate()
return out, err, process.returncode

def test_invalid_disabled_checker_name(self):
"""Error out in case of an invalid disabled checker."""
out, _, errcode = self.__run_with_invalid_disabled_checker_name([])

match = self.missing_checker_regex.search(out)
self.assertIsNotNone(match)
self.assertTrue("non-existing-checker-name" in out)

errcode = process.returncode
self.assertEqual(errcode, 1)

def test_invalid_disabled_checker_name_warn(self):
"""
Warn in case of an invalid disabled checker when using
--no-missing-checker-error.
"""
out, _, errcode = self.__run_with_invalid_disabled_checker_name(
['--no-missing-checker-error'])

match = self.missing_checker_regex.search(out)
self.assertIsNotNone(match)
self.assertTrue("non-existing-checker-name" in out)

self.assertEqual(errcode, 0)

def test_disabling_clangsa_modeling_checkers(self):
"""Warn in case a modeling checker is disabled from clangsa"""
build_json = os.path.join(self.test_workspace, "build_success.json")
Expand Down Expand Up @@ -1065,14 +1102,38 @@ def test_analyzer_and_checker_config(self):
cwd=self.test_dir,
encoding="utf-8",
errors="ignore")
out, _ = process.communicate()
out, err = process.communicate()

# It's printed as a found report and in the checker statistics.
# Note: If this test case fails, its pretty sure that something totally
# unrelated to the analysis broke in CodeChecker. Comment out the line
# starting with 'nocapture' in 'analyzer/.noserc', and print both the
# stdout and stderr streams from the above communicate() call (the
# latter of which is ignored with _ above)
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print(out)
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print(err)
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
print("%%%%%%%%%%%%%%%%%%%%%%%")
self.assertEqual(out.count('hicpp-use-nullptr'), 2)

analyze_cmd = [self._codechecker_cmd, "check", "-l", build_json,
Expand Down

0 comments on commit 16d8425

Please sign in to comment.