Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bugfix] Don't trigger analyzer without enabled checkers #3970

Merged
merged 2 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions analyzer/codechecker_analyzer/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from . import analyzer_context, analysis_manager, pre_analysis_manager, \
checkers
from .analyzers import analyzer_types
from .analyzers.config_handler import CheckerState
from .analyzers.config_handler import AnalyzerConfigHandler, CheckerState
from .analyzers.clangsa.analyzer import ClangSA

from .makefile import MakeFileCreator
Expand Down Expand Up @@ -124,6 +124,15 @@ def __get_ctu_data(ctu_dir):
'ctu_temp_fnmap_folder': 'tmpExternalFnMaps'}


def __has_enabled_checker(ch: AnalyzerConfigHandler):
"""
Returns True if at least one checker is enabled in the given config
handler.
"""
return any(state == CheckerState.enabled
for _, (state, _) in ch.checks().items())


def perform_analysis(args, skip_handlers, actions, metadata_tool,
compile_cmd_count):
"""
Expand Down Expand Up @@ -160,9 +169,16 @@ def perform_analysis(args, skip_handlers, actions, metadata_tool,
"the Clang Static Analyzer.")
return

actions = prepare_actions(actions, analyzers)
config_map = analyzer_types.build_config_handlers(args, analyzers)

no_checker_analyzers = \
[a for a in analyzers if not __has_enabled_checker(config_map[a])]
for analyzer in no_checker_analyzers:
LOG.info("No checkers enabled for %s", analyzer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we tell if the user explicitly enabled an analyzer? If so, we should hard error, shouldn't we?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can be convinced, but I would feel a hard error a little strong here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll give you that one.

analyzers.remove(analyzer)

actions = prepare_actions(actions, analyzers)

available_checkers = set()
# Add profile names to the checkers list so we will not warn
# if a profile is enabled but there is no checker with that name.
Expand Down
28 changes: 28 additions & 0 deletions analyzer/tests/functional/analyze/test_analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,34 @@ def test_makefile_generation(self):
plist_files = glob.glob(os.path.join(self.report_dir, '*.plist'))
self.assertEqual(len(plist_files), 4)

def test_disable_all_checkers(self):
"""
If all checkers of an analyzer are disabled then the analysis shouldn't
trigger for that analyzer.
"""
build_json = os.path.join(self.test_workspace, "build.json")
build_log = [{"directory": self.test_workspace,
"command": "gcc -c main.c",
"file": "main.c"}]

with open(build_json, 'w',
encoding="utf-8", errors="ignore") as outfile:
json.dump(build_log, outfile)

for analyzer in ['clangsa', 'clang-tidy']:
analyze_cmd = [self._codechecker_cmd, "check", "-l", build_json,
"--analyzers", analyzer,
"--disable", "default"]
process = subprocess.Popen(
analyze_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="utf-8",
errors="ignore")
out, _ = process.communicate()

self.assertIn(f"No checkers enabled for {analyzer}", out)

def test_analyzer_and_checker_config(self):
"""Test analyzer configuration through command line flags."""
build_json = os.path.join(self.test_workspace, "build_success.json")
Expand Down