From cbdfeccff76ae5a86f6b1679c644bd4d4bae5294 Mon Sep 17 00:00:00 2001 From: bruntib Date: Fri, 30 Jun 2023 16:19:33 +0200 Subject: [PATCH 1/3] [cmd] Eliminate default checker status Currently there are 3 kind of checkers regarding whether they are running during analysis: enabled, disabled, unknown. Checkers can be enabled if they are explicitly given to --enable flag, or they are the member of "default" profile. Checkers can also be explicitly disabled. The 3rd status is tricky: CodeChecker doesn't explicitly enable or disable them, but gives the choice to the analyzer tool. This behavior is bad, because a user cannot tell exactly which checkers were executed during analysis. It is impossible to determine in case of no error if a checker was disabled or just simply didn't report any issue. The goal in this commit is that every checker is either enabled or disabled. It is the analyzer module's responsibility to assemble an analysis command which executes at least the enabled checkers and turns off or hides the disabled ones. --- .../codechecker_analyzer/analysis_manager.py | 4 +-- .../analyzers/clangtidy/analyzer.py | 7 +++++ .../analyzers/clangtidy/config_handler.py | 2 +- .../analyzers/config_handler.py | 31 +++++++------------ .../analyzers/cppcheck/config_handler.py | 31 +------------------ analyzer/codechecker_analyzer/cmd/checkers.py | 13 +++----- .../tests/functional/analyze/test_analyze.py | 4 ++- analyzer/tests/unit/test_checker_handling.py | 30 +++++++++++------- 8 files changed, 48 insertions(+), 74 deletions(-) diff --git a/analyzer/codechecker_analyzer/analysis_manager.py b/analyzer/codechecker_analyzer/analysis_manager.py index 7ad29087e7..a41dc17644 100644 --- a/analyzer/codechecker_analyzer/analysis_manager.py +++ b/analyzer/codechecker_analyzer/analysis_manager.py @@ -329,8 +329,8 @@ def handle_failure( # from the standard output by this postprocess phase so we can present them # as CodeChecker reports. checks = source_analyzer.config_handler.checks() - state = checks.get('clang-diagnostic-error', (CheckerState.default, ''))[0] - if state != CheckerState.disabled: + state = checks.get('clang-diagnostic-error', (CheckerState.enabled, ''))[0] + if state == CheckerState.enabled: rh.postprocess_result(skip_handlers) # Remove files that successfully analyzed earlier on. diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py index 7bc5d92b95..284649cfad 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py @@ -290,6 +290,13 @@ def get_checker_list(self, config) -> Tuple[List[str], List[str]]: warning_name, warning_type = \ get_compiler_warning_name_and_type(checker_name) + + # This warning must be given a parameter separated by either '=' or + # space. This warning is not supported as a checker name so its + # special usage is avoided. + if warning_name and warning_name.startswith('frame-larger-than'): + continue + if warning_name is not None: # -W and clang-diagnostic- are added as compiler warnings. if warning_type == CheckerType.compiler: diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/config_handler.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/config_handler.py index 27200d9452..35a0d445ff 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/config_handler.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/config_handler.py @@ -33,7 +33,7 @@ def __init__(self): super(ClangTidyConfigHandler, self).__init__() def add_checker(self, checker_name, description='', - state=CheckerState.default): + state=CheckerState.disabled): """ Add additional checker if the 'take-config-from-directory' analyzer configuration option is not set. diff --git a/analyzer/codechecker_analyzer/analyzers/config_handler.py b/analyzer/codechecker_analyzer/analyzers/config_handler.py index b346f8b41d..e575c5ea57 100644 --- a/analyzer/codechecker_analyzer/analyzers/config_handler.py +++ b/analyzer/codechecker_analyzer/analyzers/config_handler.py @@ -21,18 +21,13 @@ LOG = get_logger('system') -# The baseline handling of checks in every analyzer is to let the analysis -# engine decide which checks are worthwhile run. Checks handled this way -# (implicitly by the analyzer) are considered to have a CheckerState of -# default. If the check however appears in profiles, and such a profile is -# enabled explicitly on the command-line or implicitly as in case of the -# default profile, then they are considered to have a CheckerState of enabled. -# Likewise for individually enabled checks. If a check is however explicitly -# disabled on the command-line, or belongs to a profile explicitly disabled -# on the command-line, then it is considered to have a CheckerState of -# disabled. +# If the check appears in profiles, and such a profile is enabled explicitly on +# the command-line or implicitly as in case of the default profile, then they +# are considered to have a CheckerState of enabled. Likewise for individually +# enabled checks. If a check is however explicitly disabled on the +# command-line, or belongs to a profile explicitly disabled on the +# command-line, then it is considered to have a CheckerState of disabled. class CheckerState(Enum): - default = 0 disabled = 1 enabled = 2 @@ -77,17 +72,14 @@ def __init__(self): self.report_hash = None self.enable_all = None - # The key is the checker name, the value is a tuple. - # False if disabled (should be by default). - # True if checker is enabled. - # (False/True, 'checker_description') + # The key is the checker name, the value is a tuple of CheckerState and + # checker description. self.__available_checkers = collections.OrderedDict() def add_checker(self, checker_name, description='', - state=CheckerState.default): + state=CheckerState.disabled): """ - Add additional checker. If no state argument is given, the actual usage - of the checker is handled by the analyzer. + Add a checker to the available checkers' list. """ self.__available_checkers[checker_name] = (state, description) @@ -171,8 +163,7 @@ def initialize_checkers(self, checker_labels = analyzer_context.get_context().checker_labels - # Add all checkers marked as default. This means the analyzer should - # manage whether it is enabled or disabled. + # Add all checkers marked as disabled. for checker_name, description in checkers: self.add_checker(checker_name, description) diff --git a/analyzer/codechecker_analyzer/analyzers/cppcheck/config_handler.py b/analyzer/codechecker_analyzer/analyzers/cppcheck/config_handler.py index b99a19c856..11c41ce19d 100644 --- a/analyzer/codechecker_analyzer/analyzers/cppcheck/config_handler.py +++ b/analyzer/codechecker_analyzer/analyzers/cppcheck/config_handler.py @@ -9,39 +9,10 @@ Config handler for Cppcheck analyzer. """ from .. import config_handler -from ..config_handler import CheckerState class CppcheckConfigHandler(config_handler.AnalyzerConfigHandler): """ Configuration handler for Cppcheck analyzer. """ - def initialize_checkers(self, - checkers, - cmdline_enable=None, - enable_all=False): - if not cmdline_enable: - cmdline_enable = list() - """ - Set all the default checkers to disabled. This will ensure that - --enable=all will not run with all the possible checkers - """ - super().initialize_checkers( - checkers, - cmdline_enable, - enable_all) - - # Set all the checkers with default CheckerState checkers to - # disabled. This will ensure that --enable=all will not run with - # all the possible checkers. All the checkers that are in the default - # profile (or configured othewise, eg.: from the cli) should be - # already enabled at this point. - # This happens in two phases in order to avoid iterator invalidation. - # (self.set_checker_enabled() removes elements, so we can't use it - # while iterating over the checker list.) - default_state_checkers = [ - checker_name for checker_name, data in - self.checks().items() if data[0] == CheckerState.default] - - for checker_name in default_state_checkers: - self.set_checker_enabled(checker_name, enabled=False) + pass diff --git a/analyzer/codechecker_analyzer/cmd/checkers.py b/analyzer/codechecker_analyzer/cmd/checkers.py index cd28e3b430..273ac632e3 100644 --- a/analyzer/codechecker_analyzer/cmd/checkers.py +++ b/analyzer/codechecker_analyzer/cmd/checkers.py @@ -260,9 +260,11 @@ def __get_detailed_checker_info( config_handler.initialize_checkers(checkers, profile_checkers) for checker, (state, description) in config_handler.checks().items(): + labels = cl.labels_of_checker(checker, analyzer) + state = CheckerState.enabled if ('profile', 'default') in labels \ + else CheckerState.disabled checker_info[analyzer].append( - (state, checker, analyzer, description, - sorted(cl.labels_of_checker(checker, analyzer)))) + (state, checker, analyzer, description, sorted(labels))) return checker_info @@ -385,10 +387,7 @@ def __format_row(row: Tuple) -> Tuple: row -- A tuple with detailed checker info coming from __get_detailed_checker_info() function. """ - state = '+' if row[0] == CheckerState.enabled else \ - '-' if row[0] == CheckerState.disabled else \ - '?' - + state = '+' if row[0] == CheckerState.enabled else '-' labels = ', '.join(f'{k}:{v}' for k, v in row[4]) return state, row[1], row[2], row[3], labels @@ -404,8 +403,6 @@ def __print_checkers_custom_format(checkers: Iterable): status = 'enabled' elif checker[0] == CheckerState.disabled: status = 'disabled' - else: - status = 'unknown' print(checker[1]) print(' Status:', status) diff --git a/analyzer/tests/functional/analyze/test_analyze.py b/analyzer/tests/functional/analyze/test_analyze.py index 0f19ac8659..af37563e9a 100644 --- a/analyzer/tests/functional/analyze/test_analyze.py +++ b/analyzer/tests/functional/analyze/test_analyze.py @@ -1046,7 +1046,9 @@ def test_makefile_generation(self): """ Test makefile generation. """ build_json = os.path.join(self.test_workspace, "build_extra_args.json") analyze_cmd = [self._codechecker_cmd, "analyze", build_json, - "-o", self.report_dir, '--makefile'] + "-o", self.report_dir, + "-e", "clang-diagnostic", + '--makefile'] source_file = os.path.join(self.test_dir, "extra_args.cpp") build_log = [{"directory": self.test_workspace, diff --git a/analyzer/tests/unit/test_checker_handling.py b/analyzer/tests/unit/test_checker_handling.py index fe5d23d494..b6a91073f0 100644 --- a/analyzer/tests/unit/test_checker_handling.py +++ b/analyzer/tests/unit/test_checker_handling.py @@ -110,9 +110,15 @@ def test_no_disabled_checks(self): """ Test that ClangSA only uses enable lists. """ - self.assertFalse( - any(arg.startswith('-analyzer-disable-checker') - for arg in self.__class__.cmd)) + # TODO: This test is currently removed, because checkers that are not + # enabled are explicitly disabled. In a next commit ClangSA reports + # will be hidden instead of disabled. In that commit this test could be + # re-enabled. + pass + + # self.assertFalse( + # any(arg.startswith('-analyzer-disable-checker') + # for arg in self.__class__.cmd)) def test_checker_initializer(self): """ @@ -161,19 +167,19 @@ def f(checks, checkers): checkers.extend(map(add_description, statisticsbased)) # "default" profile checkers are enabled explicitly. Others are in - # "default" state. + # "disabled" state. cfg_handler = ClangSA.construct_config_handler(args) cfg_handler.initialize_checkers(checkers) self.assertTrue(all_with_status(CheckerState.enabled) (cfg_handler.checks(), default_profile)) - self.assertTrue(all_with_status(CheckerState.default) + self.assertTrue(all_with_status(CheckerState.disabled) (cfg_handler.checks(), security_profile_alpha)) - # "--enable-all" leaves alpha checkers in "default" state. Others + # "--enable-all" leaves alpha checkers in "disabled" state. Others # become enabled. cfg_handler = ClangSA.construct_config_handler(args) cfg_handler.initialize_checkers(checkers, enable_all=True) - self.assertTrue(all_with_status(CheckerState.default) + self.assertTrue(all_with_status(CheckerState.disabled) (cfg_handler.checks(), security_profile_alpha)) self.assertTrue(all_with_status(CheckerState.enabled) (cfg_handler.checks(), default_profile)) @@ -333,15 +339,15 @@ def test_default_checkers_are_not_disabled(self): self.assertFalse('-*' in self.__class__.checks_list) - def test_only_clangsa_analyzer_checks_are_disabled(self): + def test_clangsa_analyzer_checks_are_disabled(self): """ - Test that exactly the clang-analyzer group is disabled in Clang Tidy. + Test that the clang-analyzer group is disabled in Clang Tidy. """ self.assertTrue('-clang-analyzer-*' in self.__class__.checks_list) - self.assertFalse( - any(check.startswith('-') and check != '-clang-analyzer-*' - for check in self.__class__.checks_list)) + # self.assertFalse( + # any(check.startswith('-') and check != '-clang-analyzer-*' + # for check in self.__class__.checks_list)) def test_clang_diags_as_compiler_warnings(self): """ From f2949d2b92d415f7cf87365585bf79569cc8f987 Mon Sep 17 00:00:00 2001 From: bruntib Date: Tue, 4 Jul 2023 13:33:32 +0200 Subject: [PATCH 2/3] [feat] ClangTidy enables only selected checkers Due to the previous commit every checker is either enabled or disabled. This resulted very long analyzer commands in ClangTidy because every checker was explicitly enabled or disabled in the clang-tidy invocation. ClangTidy has a lot of checkers and also all compiler warnings listed by diagtool are also considered as checkers. The goal of this commit is to simplify the clang-tidy invocation command. First we disable all checkers and enable only those that are necessary to run: clang-tidy -checks=-*,enabled1,enabled2... This patch takes into account that clang-diagnostic-... checkers don't turn on the corresponding warnings. They have to be enabled by -W... compiler flag. --- .../analyzers/clangtidy/analyzer.py | 102 ++++++++++++---- ...r_warning_default_checker_priority.output} | 33 ++++- .../context_free_hash_clang_tidy.output | 4 +- .../context_free_hash_v2_clang_tidy.output | 4 +- .../context_sensitive_hash_clang_tidy.output | 4 +- .../diagnostic_message_hash_clang_tidy.output | 4 +- .../test_files/source_code_comments.output | 4 +- .../source_code_comments_all.output | 4 +- ...urce_code_comments_all_empty_filter.output | 4 +- .../source_code_comments_confirmed.output | 4 +- ...source_code_comments_false_positive.output | 4 +- .../test_files/tidy_check.output | 4 +- analyzer/tests/unit/test_checker_handling.py | 101 +++++++++++++--- config/labels/analyzers/clang-tidy.json | 113 +++++++++++++++++- .../functional/component/test_component.py | 2 +- .../detection_status/test_detection_status.py | 2 +- .../functional/diff_local/test_diff_local.py | 8 +- .../functional/report_viewer_api/__init__.py | 79 +++++++++++- .../source_change/test_source_change.py | 2 +- 19 files changed, 410 insertions(+), 72 deletions(-) rename analyzer/tests/functional/analyze_and_parse/test_files/{compiler_warning_no_warn.output => compiler_warning_default_checker_priority.output} (53%) diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py index 284649cfad..239208be05 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py @@ -16,7 +16,7 @@ import re import shlex import subprocess -from typing import List, Tuple +from typing import Iterable, List, Set, Tuple import yaml @@ -165,6 +165,45 @@ def get_warnings(env=None): raise +def _add_asterisk_for_group( + subset_checkers: Iterable[str], + all_checkers: Set[str] +) -> List[str]: + """ + Since CodeChecker interprets checker name prefixes as checker groups, they + have to be added a '*' joker character when using them at clang-tidy + -checks flag. This function adds a '*' for each item in "checkers" if it's + a checker group, i.e. identified as a prefix for any checker name in + "all_checkers". + For example "readability-container" is a prefix of multiple checkers, so + this is converted to "readability-container-*". On the other hand + "performance-trivially-destructible" is a full checker name, so it remains + as is. + """ + def is_group_prefix_of(prefix: str, long: str) -> bool: + """ + Returns True if a checker(-group) name is prefix of another + checker name. For example bugprone-string is prefix of + bugprone-string-constructor but not of + bugprone-stringview-nullptr. + """ + prefix_split = prefix.split('-') + long_split = long.split('-') + return prefix_split == long_split[:len(prefix_split)] + + def need_asterisk(checker: str) -> bool: + return any( + is_group_prefix_of(checker, long) and checker != long + for long in all_checkers) + + result = [] + + for checker in subset_checkers: + result.append(checker + ('*' if need_asterisk(checker) else '')) + + return result + + class ClangTidy(analyzer_base.SourceAnalyzer): """ Constructs the clang tidy analyzer commands. @@ -172,6 +211,9 @@ class ClangTidy(analyzer_base.SourceAnalyzer): ANALYZER_NAME = 'clang-tidy' + # Cache object for get_analyzer_checkers(). + __analyzer_checkers = None + @classmethod def analyzer_binary(cls): return analyzer_context.get_context() \ @@ -204,6 +246,9 @@ def get_analyzer_checkers(cls): Return the list of the all of the supported checkers. """ try: + if cls.__analyzer_checkers: + return cls.__analyzer_checkers + environ = analyzer_context.get_context().analyzer_env result = subprocess.check_output( [cls.analyzer_binary(), "-list-checks", "-checks=*"], @@ -217,6 +262,8 @@ def get_analyzer_checkers(cls): ("clang-diagnostic-" + warning, "") for warning in get_warnings(environ)) + cls.__analyzer_checkers = checker_description + return checker_description except (subprocess.CalledProcessError, OSError): return [] @@ -266,24 +313,30 @@ def get_checker_list(self, config) -> Tuple[List[str], List[str]]: clang-tidy and in some cases that would cause analysis error due to some ClangSA bug. """ - checkers = [] - # Usage of a set will remove compiler warnings and clang-diagnostics - # which are the same. + # clang-tidy emits reports from its check in the same format as + # compiler diagnostics (like unused variables, etc). This makes it a + # little difficult to distinguish compiler warnings and clang-tidy + # check warnings. The only clue is that compiler warnings are emitted + # as if they came from a check called clang-diagnostic- (e.g. + # -Wunused-variable will emit a warning under the name + # clang-diagnostic-unused-variable). + + # There are two ways to disable a compiler warning in clang-tidy, + # either by -Wno- or -checks=-clang-diagnostic- (note the dash before + # clang-diagnostic!). However, there is only one way to enable them: + # through -W. Using -checks=clang-diagnostic- does not enable the + # warning, but undoes -checks=-clang-diagnostic-. + + # Since we disable all checks by default via -checks=-*, in order to + # enable a compiler warning, we first have to undo the -checks level + # disable and then enable it, so we need both + # -checks=compiler-diagnostic- and -W. compiler_warnings = set() + enabled_checkers = set() has_checker_config = \ config.checker_config and config.checker_config != '{}' - # Do not disable any clang-tidy checks explicitly, but don't run - # ClangSA checkers. ClangSA checkers are driven by an other - # analyzer in CodeChecker. - checkers.append('-clang-analyzer-*') - - # For clang compiler warnings a correspoding - # clang-diagnostic error is generated by Clang tidy. - # They can be disabled by this glob -clang-diagnostic-* - checkers.append('clang-diagnostic-*') - # Config handler stores which checkers are enabled or disabled. for checker_name, value in config.checks().items(): state, _ = value @@ -307,12 +360,12 @@ def get_checker_list(self, config) -> Tuple[List[str], List[str]]: "instead.") if state == CheckerState.enabled: compiler_warnings.add('-W' + warning_name) + enabled_checkers.add(checker_name) elif state == CheckerState.disabled: if config.enable_all: LOG.warning("Disabling compiler warning with " f"compiler flag '-d W{warning_name}' " "is not supported.") - compiler_warnings.add('-Wno-' + warning_name) # If a clang-diagnostic-... is enabled add it as a compiler # warning as -W..., if it is disabled, tidy can suppress when # specified in the -checks parameter list, so we add it there @@ -320,15 +373,21 @@ def get_checker_list(self, config) -> Tuple[List[str], List[str]]: elif warning_type == CheckerType.analyzer: if state == CheckerState.enabled: compiler_warnings.add('-W' + warning_name) - elif state == CheckerState.disabled: - checkers.append('-' + checker_name) + enabled_checkers.add(checker_name) continue if state == CheckerState.enabled: - checkers.append(checker_name) - elif state == CheckerState.disabled: - checkers.append('-' + checker_name) + enabled_checkers.add(checker_name) + + # By default all checkers are disabled and the enabled ones are added + # explicitly. + checkers = ['-*'] + + checkers += _add_asterisk_for_group( + enabled_checkers, + set(x[0] for x in ClangTidy.get_analyzer_checkers())) + # -checks=-clang-analyzer-* option is added to the analyzer command by # default except when all analyzer config options come from .clang-tidy # file. The content of this file overrides every other custom config @@ -385,7 +444,8 @@ def construct_analyzer_cmd(self, result_handler): analyzer_cmd.append('-Qunused-arguments') # Enable these compiler warnings by default. - analyzer_cmd.extend(['-Wall', '-Wextra']) + if not config.enable_all: + analyzer_cmd.extend(['-Wno-everything']) compile_lang = self.buildaction.lang diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_no_warn.output b/analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_default_checker_priority.output similarity index 53% rename from analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_no_warn.output rename to analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_default_checker_priority.output index bc10743cad..e164c3131b 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_no_warn.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/compiler_warning_default_checker_priority.output @@ -18,11 +18,40 @@ CHECK#CodeChecker check --build "make compiler_warning_simple" --output $OUTPUT$ [] - To store results use the "CodeChecker store" command. [] - See --help and the user guide for further options about parsing and storing the reports. [] - ----=================---- -Found no defects in compiler_warning.cpp +[MEDIUM] compiler_warning.cpp:3:7: unused variable 'i' [clang-diagnostic-unused-variable] + int i; + ^ + +Found 1 defect(s) in compiler_warning.cpp + + +----==== Severity Statistics ====---- +---------------------------- +Severity | Number of reports +---------------------------- +MEDIUM | 1 +---------------------------- +----=================---- + +----==== Checker Statistics ====---- +--------------------------------------------------------------- +Checker name | Severity | Number of reports +--------------------------------------------------------------- +clang-diagnostic-unused-variable | MEDIUM | 1 +--------------------------------------------------------------- +----=================---- + +----==== File Statistics ====---- +---------------------------------------- +File name | Number of reports +---------------------------------------- +compiler_warning.cpp | 1 +---------------------------------------- +----=================---- ----======== Summary ========---- --------------------------------------------- Number of processed analyzer result files | 1 -Number of analyzer reports | 0 +Number of analyzer reports | 1 --------------------------------------------- ----=================---- diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_clang_tidy.output b/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_clang_tidy.output index 1e82265f56..99c5d26c6e 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_clang_tidy.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_clang_tidy.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make context_hash" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --report-hash=context-free --analyzers clang-tidy +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --report-hash=context-free --analyzers clang-tidy --disable clang-diagnostic-unused-but-set-variable --disable clang-diagnostic-unused-but-set-parameter NORMAL#CodeChecker parse $OUTPUT$ --print-steps -CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --report-hash=context-free --analyzers clang-tidy +CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --report-hash=context-free --analyzers clang-tidy --disable clang-diagnostic-unused-but-set-variable --disable clang-diagnostic-unused-but-set-parameter -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_v2_clang_tidy.output b/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_v2_clang_tidy.output index 4367ad37bf..5b37f05be1 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_v2_clang_tidy.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_v2_clang_tidy.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make context_hash" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --report-hash=context-free-v2 --analyzers clang-tidy +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --report-hash=context-free-v2 --analyzers clang-tidy --disable clang-diagnostic-unused-but-set-variable --disable clang-diagnostic-unused-but-set-parameter NORMAL#CodeChecker parse $OUTPUT$ --print-steps -CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --report-hash=context-free-v2 --analyzers clang-tidy +CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --report-hash=context-free-v2 --analyzers clang-tidy --disable clang-diagnostic-unused-but-set-variable --disable clang-diagnostic-unused-but-set-parameter -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/context_sensitive_hash_clang_tidy.output b/analyzer/tests/functional/analyze_and_parse/test_files/context_sensitive_hash_clang_tidy.output index 4bf94d3e6f..fc5d256791 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/context_sensitive_hash_clang_tidy.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/context_sensitive_hash_clang_tidy.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make context_hash" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --disable clang-diagnostic-unused-but-set-variable --disable clang-diagnostic-unused-but-set-parameter NORMAL#CodeChecker parse $OUTPUT$ --print-steps -CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --analyzers clang-tidy +CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --analyzers clang-tidy --disable clang-diagnostic-unused-but-set-variable --disable clang-diagnostic-unused-but-set-parameter -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/diagnostic_message_hash_clang_tidy.output b/analyzer/tests/functional/analyze_and_parse/test_files/diagnostic_message_hash_clang_tidy.output index 1367a8d3f5..5783da06fd 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/diagnostic_message_hash_clang_tidy.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/diagnostic_message_hash_clang_tidy.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make context_hash" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --report-hash=diagnostic-message --analyzers clang-tidy +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --report-hash=diagnostic-message --analyzers clang-tidy --disable clang-diagnostic-unused-but-set-variable --disable clang-diagnostic-unused-but-set-parameter NORMAL#CodeChecker parse $OUTPUT$ --print-steps -CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --report-hash=diagnostic-message --analyzers clang-tidy +CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --report-hash=diagnostic-message --analyzers clang-tidy --disable clang-diagnostic-unused-but-set-variable --disable clang-diagnostic-unused-but-set-parameter -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments.output b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments.output index e3e01a2371..c2eab67c72 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make source_code_comments" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value NORMAL#CodeChecker parse $OUTPUT$ -CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression +CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_all.output b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_all.output index 4550d2e10c..43569a331d 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_all.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_all.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make source_code_comments" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value NORMAL#CodeChecker parse $OUTPUT$ --review-status unreviewed confirmed false_positive intentional -CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --review-status unreviewed confirmed false_positive intentional +CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value --review-status unreviewed confirmed false_positive intentional -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_all_empty_filter.output b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_all_empty_filter.output index 03199c7553..5ca646de8a 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_all_empty_filter.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_all_empty_filter.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make source_code_comments" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value NORMAL#CodeChecker parse $OUTPUT$ --review-status -CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --review-status +CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value --review-status -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_confirmed.output b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_confirmed.output index 65cefea91b..5a51aa8dd7 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_confirmed.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_confirmed.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make source_code_comments" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value NORMAL#CodeChecker parse $OUTPUT$ --review-status confirmed -CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --review-status confirmed +CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value --review-status confirmed -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_false_positive.output b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_false_positive.output index e9cce19bb1..398c9adba8 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_false_positive.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/source_code_comments_false_positive.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make source_code_comments" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value NORMAL#CodeChecker parse $OUTPUT$ --review-status false_positive -CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --review-status false_positive +CHECK#CodeChecker check --build "make source_code_comments" --output $OUTPUT$ --quiet --analyzers clang-tidy --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-value --review-status false_positive -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/tidy_check.output b/analyzer/tests/functional/analyze_and_parse/test_files/tidy_check.output index 04c965f862..b53f281bff 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/tidy_check.output +++ b/analyzer/tests/functional/analyze_and_parse/test_files/tidy_check.output @@ -1,7 +1,7 @@ NORMAL#CodeChecker log --output $LOGFILE$ --build "make tidy_check" --quiet -NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --disable misc --enable bugprone-sizeof-expression +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers clang-tidy --disable misc --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-variable NORMAL#CodeChecker parse $OUTPUT$ -CHECK#CodeChecker check --build "make tidy_check" --output $OUTPUT$ --quiet --analyzers clang-tidy --disable misc --enable bugprone-sizeof-expression +CHECK#CodeChecker check --build "make tidy_check" --output $OUTPUT$ --quiet --analyzers clang-tidy --disable misc --enable bugprone-sizeof-expression --disable clang-diagnostic-unused-variable -------------------------------------------------------------------------------- [] - Starting build... [] - Using CodeChecker ld-logger. diff --git a/analyzer/tests/unit/test_checker_handling.py b/analyzer/tests/unit/test_checker_handling.py index b6a91073f0..e2145cc5c3 100644 --- a/analyzer/tests/unit/test_checker_handling.py +++ b/analyzer/tests/unit/test_checker_handling.py @@ -13,6 +13,7 @@ from distutils import util import os +import re import unittest from argparse import Namespace @@ -26,7 +27,7 @@ from codechecker_analyzer.buildlog import log_parser -class MockCheckerLabels: +class MockClangsaCheckerLabels: def checkers_by_labels(self, labels): if labels[0] == 'profile:default': return ['core', 'deadcode', 'security.FloatLoopCounter'] @@ -89,7 +90,7 @@ class CheckerHandlingClangSATest(unittest.TestCase): @classmethod def setUpClass(cls): context = analyzer_context.get_context() - context._checker_labels = MockCheckerLabels() + context._checker_labels = MockClangsaCheckerLabels() analyzer = create_analyzer_sa() result_handler = create_result_handler(analyzer) @@ -265,6 +266,26 @@ def f(checks, checkers): any(stat_checker in c for c in enabled_checkers)) +class MockClangTidyCheckerLabels: + def checkers_by_labels(self, labels): + if labels[0] == 'profile:default': + return [ + 'bugprone-assert-side-effect', + 'bugprone-dangling-handle', + 'bugprone-inaccurate-erase'] + + def get_description(self, label): + if label == 'profile': + return ['default', 'sensitive', 'security', 'portability', + 'extreme'] + + def occurring_values(self, label): + if label == 'guideline': + return ['sei-cert'] + elif label == 'sei-cert': + return ['rule1', 'rule2'] + + def create_analyzer_tidy(args=[]): cfg_handler = ClangTidy.construct_config_handler(args) @@ -285,15 +306,59 @@ class CheckerHandlingClangTidyTest(unittest.TestCase): @classmethod def setUpClass(cls): + context = analyzer_context.get_context() + context._checker_labels = MockClangTidyCheckerLabels() + analyzer = create_analyzer_tidy() result_handler = create_result_handler(analyzer) cls.cmd = analyzer.construct_analyzer_cmd(result_handler) print('Analyzer command: %s' % cls.cmd) - checks_arg = cls.cmd[1] - checks = checks_arg[len('-checks='):] - cls.checks_list = checks.split(',') - print('Checks list: %s' % cls.checks_list) + def _enable_disable_pos(self, checker, checks_list): + """ + This function returns the positions of the patterns in "clang-tidy + -checks=..." flag where the given checker has been enabled and disabled + respectively. For example: + + clang-tidy -checks=-*,a,b*,-c + + "a": enabled->1, disabled->0 + "b": enabled->2, disabled->0 + "bx": enabled->2, disabled->0 + "c": enabled->-1, disabled->3 + + If "enabled" position is greater than "disabled" position then the + checker itself is enabled. + """ + def checker_matches(pattern, checker): + return bool(re.match(pattern.replace('*', '.*') + '$', checker)) + + enable_pos = next(( + i for i, c in enumerate(checks_list) if + checker_matches(c, checker)), -1) + disable_pos = next(reversed([ + i for i, c in enumerate(checks_list) if + checker_matches(c, '-' + checker)]), -1) + + return enable_pos, disable_pos + + def _is_disabled(self, checker, analyzer_cmd): + """ + Returns True if the "checker" is disabled for clang-tidy given the + analyzer command. + """ + checks = next(filter( + lambda arg: arg.startswith('-checks='), + analyzer_cmd), None) + + if not checks: + return True + + enable, disable = self._enable_disable_pos( + checker, + checks[len('-checks='):].split(',')) + + return enable < disable def test_disable_clangsa_checkers(self): """ @@ -302,16 +367,16 @@ def test_disable_clangsa_checkers(self): analyzer = create_analyzer_tidy() result_handler = create_result_handler(analyzer) - for arg in analyzer.construct_analyzer_cmd(result_handler): - if arg.startswith('-checks='): - self.assertIn('-clang-analyzer-*', arg) + self.assertTrue(self._is_disabled( + 'clang-analyzer', + analyzer.construct_analyzer_cmd(result_handler))) analyzer.config_handler.checker_config = \ '{"Checks": "hicpp-use-nullptr"}' - for arg in analyzer.construct_analyzer_cmd(result_handler): - if arg.startswith('-checks='): - self.assertIn('-clang-analyzer-*', arg) + self.assertTrue(self._is_disabled( + 'clang-analyzer', + analyzer.construct_analyzer_cmd(result_handler))) self.assertTrue(is_compiler_warning('Wreserved-id-macro')) self.assertFalse(is_compiler_warning('hicpp')) @@ -336,18 +401,18 @@ def test_default_checkers_are_not_disabled(self): """ Test that the default checks are not disabled in Clang Tidy. """ + checker_labels = MockClangTidyCheckerLabels() - self.assertFalse('-*' in self.__class__.checks_list) + for checker in checker_labels.checkers_by_labels(['profile:default']): + self.assertFalse(self._is_disabled( + checker, self.__class__.cmd)) def test_clangsa_analyzer_checks_are_disabled(self): """ Test that the clang-analyzer group is disabled in Clang Tidy. """ - - self.assertTrue('-clang-analyzer-*' in self.__class__.checks_list) - # self.assertFalse( - # any(check.startswith('-') and check != '-clang-analyzer-*' - # for check in self.__class__.checks_list)) + self.assertTrue(self._is_disabled( + 'clang-analyzer', self.__class__.cmd)) def test_clang_diags_as_compiler_warnings(self): """ diff --git a/config/labels/analyzers/clang-tidy.json b/config/labels/analyzers/clang-tidy.json index 8bbfdaaa31..c8bf41654c 100644 --- a/config/labels/analyzers/clang-tidy.json +++ b/config/labels/analyzers/clang-tidy.json @@ -633,7 +633,7 @@ "sei-cert:exp63-cpp", "severity:MEDIUM" ], - "bugprone-unsafe-functions":[ + "bugprone-unsafe-functions": [ "doc_url:https://clang.llvm.org/extra/clang-tidy/checks/bugprone/unsafe-functions.html", "guideline:sei-cert", "profile:extreme", @@ -1287,14 +1287,17 @@ ], "clang-diagnostic-bitwise-conditional-parentheses": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wbitwise-conditional-parentheses", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-bitwise-instead-of-logical": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wbitwise-instead-of-logical", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-bitwise-op-parentheses": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wbitwise-op-parentheses", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-block-capture-autoreleasing": [ @@ -1311,6 +1314,7 @@ ], "clang-diagnostic-bool-operation": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wbool-operation", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-braced-scalar-init": [ @@ -1571,6 +1575,7 @@ ], "clang-diagnostic-cast-of-sel-type": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wcast-of-sel-type", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-cast-qual": [ @@ -1591,6 +1596,7 @@ ], "clang-diagnostic-char-subscripts": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wchar-subscripts", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-cl4": [ @@ -1619,6 +1625,7 @@ ], "clang-diagnostic-comment": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wcomment", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-comments": [ @@ -1747,6 +1754,7 @@ ], "clang-diagnostic-dangling-else": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wdangling-else", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-dangling-field": [ @@ -1791,6 +1799,7 @@ ], "clang-diagnostic-delete-abstract-non-virtual-dtor": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wdelete-abstract-non-virtual-dtor", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-delete-incomplete": [ @@ -1799,10 +1808,12 @@ ], "clang-diagnostic-delete-non-abstract-non-virtual-dtor": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wdelete-non-abstract-non-virtual-dtor", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-delete-non-virtual-dtor": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wdelete-non-virtual-dtor", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-delimited-escape-sequence-extension": [ @@ -1843,6 +1854,7 @@ ], "clang-diagnostic-deprecated-copy": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wdeprecated-copy", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-deprecated-copy-dtor": [ @@ -1855,6 +1867,7 @@ ], "clang-diagnostic-deprecated-copy-with-user-provided-copy": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wdeprecated-copy-with-user-provided-copy", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-deprecated-copy-with-user-provided-dtor": [ @@ -1967,6 +1980,7 @@ ], "clang-diagnostic-division-by-zero": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wdivision-by-zero", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-dll-attribute-on-redeclaration": [ @@ -2085,6 +2099,7 @@ ], "clang-diagnostic-empty-init-stmt": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wempty-init-stmt", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-empty-translation-unit": [ @@ -2172,6 +2187,7 @@ ], "clang-diagnostic-extern-c-compat": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wextern-c-compat", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-extern-initializer": [ @@ -2244,10 +2260,12 @@ ], "clang-diagnostic-for-loop-analysis": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wfor-loop-analysis", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-format": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wformat", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-format-2": [ @@ -2256,14 +2274,17 @@ ], "clang-diagnostic-format-extra-args": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wformat-extra-args", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-format-insufficient-args": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wformat-insufficient-args", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-format-invalid-specifier": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wformat-invalid-specifier", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-format-non-iso": [ @@ -2281,6 +2302,7 @@ ], "clang-diagnostic-format-security": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wformat-security", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-format-type-confusion": [ @@ -2289,10 +2311,12 @@ ], "clang-diagnostic-format-y2k": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wformat-y2k", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-format-zero-length": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wformat-zero-length", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-format=2": [ @@ -2309,6 +2333,7 @@ ], "clang-diagnostic-frame-address": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wframe-address", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-frame-larger-than": [ @@ -2337,6 +2362,7 @@ ], "clang-diagnostic-fuse-ld-path": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wfuse-ld-path", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-future-attribute-extensions": [ @@ -2545,14 +2571,17 @@ ], "clang-diagnostic-ignored-qualifiers": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wignored-qualifiers", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-ignored-reference-qualifiers": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wignored-reference-qualifiers", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-implicit": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wimplicit", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-implicit-atomic-properties": [ @@ -2589,10 +2618,12 @@ ], "clang-diagnostic-implicit-function-declaration": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wimplicit-function-declaration", + "profile:default", "severity:HIGH" ], "clang-diagnostic-implicit-int": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wimplicit-int", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-implicit-int-conversion": [ @@ -2709,6 +2740,7 @@ ], "clang-diagnostic-infinite-recursion": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#winfinite-recursion", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-init-self": [ @@ -2717,6 +2749,7 @@ ], "clang-diagnostic-initializer-overrides": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#winitializer-overrides", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-injected-class-name": [ @@ -2753,6 +2786,7 @@ ], "clang-diagnostic-int-in-bool-context": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wint-in-bool-context", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-int-to-pointer-cast": [ @@ -2877,10 +2911,12 @@ ], "clang-diagnostic-logical-not-parentheses": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wlogical-not-parentheses", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-logical-op-parentheses": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wlogical-op-parentheses", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-long-long": [ @@ -3077,6 +3113,7 @@ ], "clang-diagnostic-misleading-indentation": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wmisleading-indentation", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-mismatched-new-delete": [ @@ -3093,10 +3130,12 @@ ], "clang-diagnostic-mismatched-tags": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wmismatched-tags", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-missing-braces": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-braces", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-missing-constinit": [ @@ -3113,6 +3152,7 @@ ], "clang-diagnostic-missing-field-initializers": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-field-initializers", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-missing-format-attribute": [ @@ -3125,6 +3165,7 @@ ], "clang-diagnostic-missing-method-return-type": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-method-return-type", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-missing-noescape": [ @@ -3201,10 +3242,12 @@ ], "clang-diagnostic-most": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wmost", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-move": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wmove", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-msvc-include": [ @@ -3217,6 +3260,7 @@ ], "clang-diagnostic-multichar": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wmultichar", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-multiple-move-vbase": [ @@ -3288,6 +3332,7 @@ ], "clang-diagnostic-nonnull": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wnonnull", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-nonportable-cfstrings": [ @@ -3340,10 +3385,12 @@ ], "clang-diagnostic-null-pointer-arithmetic": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wnull-pointer-arithmetic", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-null-pointer-subtraction": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wnull-pointer-subtraction", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-nullability": [ @@ -3396,6 +3443,7 @@ ], "clang-diagnostic-objc-designated-initializers": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wobjc-designated-initializers", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-objc-dictionary-duplicate-keys": [ @@ -3404,6 +3452,7 @@ ], "clang-diagnostic-objc-flexible-array": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wobjc-flexible-array", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-objc-forward-class-redefinition": [ @@ -3440,6 +3489,7 @@ ], "clang-diagnostic-objc-missing-super-calls": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wobjc-missing-super-calls", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-objc-multiple-method-names": [ @@ -3600,10 +3650,12 @@ ], "clang-diagnostic-overloaded-shift-op-parentheses": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#woverloaded-shift-op-parentheses", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-overloaded-virtual": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#woverloaded-virtual", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-override-init": [ @@ -3636,10 +3688,12 @@ ], "clang-diagnostic-parentheses": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wparentheses", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-parentheses-equality": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wparentheses-equality", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-partial-availability": [ @@ -3680,6 +3734,7 @@ ], "clang-diagnostic-pessimizing-move": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wpessimizing-move", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-pointer-arith": [ @@ -3724,6 +3779,7 @@ ], "clang-diagnostic-potentially-evaluated-expression": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wpotentially-evaluated-expression", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-pragma-clang-attribute": [ @@ -3800,6 +3856,7 @@ ], "clang-diagnostic-private-extern": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wprivate-extern", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-private-header": [ @@ -3868,6 +3925,7 @@ ], "clang-diagnostic-range-loop-construct": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wrange-loop-construct", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-readonly-iboutlet-property": [ @@ -3896,6 +3954,7 @@ ], "clang-diagnostic-redundant-move": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wredundant-move", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-redundant-parens": [ @@ -3916,14 +3975,17 @@ ], "clang-diagnostic-reorder": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wreorder", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-reorder-ctor": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wreorder-ctor", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-reorder-init-list": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wreorder-init-list", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-requires-super-attribute": [ @@ -3968,14 +4030,17 @@ ], "clang-diagnostic-return-std-move": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wreturn-std-move", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-return-type": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wreturn-type", + "profile:default", "severity:HIGH" ], "clang-diagnostic-return-type-c-linkage": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wreturn-type-c-linkage", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-rewrite-not-bool": [ @@ -4016,22 +4081,27 @@ ], "clang-diagnostic-self-assign": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wself-assign", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-self-assign-field": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wself-assign-field", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-self-assign-overloaded": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wself-assign-overloaded", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-self-move": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wself-move", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-semicolon-before-method-body": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wsemicolon-before-method-body", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-sentinel": [ @@ -4088,6 +4158,7 @@ ], "clang-diagnostic-shift-op-parentheses": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wshift-op-parentheses", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-shift-overflow": [ @@ -4104,6 +4175,7 @@ ], "clang-diagnostic-sign-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wsign-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-sign-conversion": [ @@ -4128,10 +4200,12 @@ ], "clang-diagnostic-sizeof-array-argument": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wsizeof-array-argument", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-sizeof-array-decay": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wsizeof-array-decay", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-sizeof-array-div": [ @@ -4160,6 +4234,7 @@ ], "clang-diagnostic-sometimes-uninitialized": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wsometimes-uninitialized", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-source-mgr": [ @@ -4207,6 +4282,7 @@ ], "clang-diagnostic-static-self-init": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wstatic-self-init", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-stdlibcxx-not-found": [ @@ -4275,6 +4351,7 @@ ], "clang-diagnostic-string-concatenation": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wstring-concatenation", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-string-conversion": [ @@ -4287,6 +4364,7 @@ ], "clang-diagnostic-string-plus-int": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wstring-plus-int", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-strlcpy-strlcat-size": [ @@ -4323,10 +4401,12 @@ ], "clang-diagnostic-switch": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wswitch", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-switch-bool": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wswitch-bool", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-switch-default": [ @@ -4355,14 +4435,17 @@ ], "clang-diagnostic-tautological-bitwise-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtautological-bitwise-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-tautological-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtautological-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-tautological-constant-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtautological-constant-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-tautological-constant-in-range-compare": [ @@ -4371,18 +4454,22 @@ ], "clang-diagnostic-tautological-constant-out-of-range-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtautological-constant-out-of-range-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-tautological-objc-bool-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtautological-objc-bool-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-tautological-overlap-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtautological-overlap-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-tautological-pointer-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtautological-pointer-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-tautological-type-limit-compare": [ @@ -4391,6 +4478,7 @@ ], "clang-diagnostic-tautological-undefined-compare": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtautological-undefined-compare", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-tautological-unsigned-char-zero-compare": [ @@ -4451,6 +4539,7 @@ ], "clang-diagnostic-trigraphs": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wtrigraphs", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-troduction": [ @@ -4535,6 +4624,7 @@ ], "clang-diagnostic-unevaluated-expression": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunevaluated-expression", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unguarded-availability": [ @@ -4563,10 +4653,12 @@ ], "clang-diagnostic-uninitialized": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wuninitialized", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-uninitialized-const-reference": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wuninitialized-const-reference", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unknown-argument": [ @@ -4595,6 +4687,7 @@ ], "clang-diagnostic-unknown-pragmas": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunknown-pragmas", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unknown-sanitizers": [ @@ -4611,6 +4704,7 @@ ], "clang-diagnostic-unneeded-internal-declaration": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunneeded-internal-declaration", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unneeded-member-function": [ @@ -4711,14 +4805,17 @@ ], "clang-diagnostic-unused-argument": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-argument", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-but-set-parameter": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-but-set-parameter", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-but-set-variable": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-but-set-variable", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-command-line-argument": [ @@ -4727,10 +4824,12 @@ ], "clang-diagnostic-unused-comparison": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-comparison", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-const-variable": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-const-variable", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-exception-parameter": [ @@ -4739,6 +4838,7 @@ ], "clang-diagnostic-unused-function": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-function", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-getter-return-value": [ @@ -4747,14 +4847,17 @@ ], "clang-diagnostic-unused-label": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-label", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-lambda-capture": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-lambda-capture", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-local-typedef": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-local-typedef", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-local-typedefs": [ @@ -4771,18 +4874,22 @@ ], "clang-diagnostic-unused-parameter": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-parameter", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-private-field": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-private-field", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-property-ivar": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-property-ivar", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-result": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-result", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-template": [ @@ -4791,10 +4898,12 @@ ], "clang-diagnostic-unused-value": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-value", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-variable": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-variable", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-unused-volatile-lvalue": [ @@ -4811,6 +4920,7 @@ ], "clang-diagnostic-user-defined-warnings": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wuser-defined-warnings", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-varargs": [ @@ -4863,6 +4973,7 @@ ], "clang-diagnostic-volatile-register-var": [ "doc_url:https://clang.llvm.org/docs/DiagnosticsReference.html#wvolatile-register-var", + "profile:default", "severity:MEDIUM" ], "clang-diagnostic-wasm-exception-spec": [ diff --git a/web/tests/functional/component/test_component.py b/web/tests/functional/component/test_component.py index c6f92810ec..e14821d20a 100644 --- a/web/tests/functional/component/test_component.py +++ b/web/tests/functional/component/test_component.py @@ -64,7 +64,7 @@ def setup_class(self): 'skip_list_file': skip_list_file, 'check_env': test_env, 'workspace': TEST_WORKSPACE, - 'checkers': [], + 'checkers': ['-d', 'clang-diagnostic'], 'analyzers': ['clangsa', 'clang-tidy'] } diff --git a/web/tests/functional/detection_status/test_detection_status.py b/web/tests/functional/detection_status/test_detection_status.py index 23c4d1e0b5..d04635b746 100644 --- a/web/tests/functional/detection_status/test_detection_status.py +++ b/web/tests/functional/detection_status/test_detection_status.py @@ -38,7 +38,7 @@ def setup_class(self): 'skip_list_file': None, 'check_env': env.test_env(TEST_WORKSPACE), 'workspace': TEST_WORKSPACE, - 'checkers': [], + 'checkers': ['-d', 'clang-diagnostic'], 'reportdir': os.path.join(TEST_WORKSPACE, 'reports'), 'test_project': 'hello', 'analyzers': ['clangsa', 'clang-tidy'] diff --git a/web/tests/functional/diff_local/test_diff_local.py b/web/tests/functional/diff_local/test_diff_local.py index c51ecc30f5..e15f2e29a2 100644 --- a/web/tests/functional/diff_local/test_diff_local.py +++ b/web/tests/functional/diff_local/test_diff_local.py @@ -77,7 +77,7 @@ def setup_class(self): 'skip_list_file': skip_list_file, 'check_env': test_env, 'workspace': TEST_WORKSPACE, - 'checkers': [], + 'checkers': ['-d', 'clang-diagnostic'], 'analyzers': ['clangsa', 'clang-tidy'] } @@ -85,7 +85,8 @@ def setup_class(self): codechecker_cfg['reportdir'] = os.path.join(test_proj_path_base, 'reports') codechecker_cfg['checkers'] = ['-e', 'core.CallAndMessage', - '-d', 'core.NullDereference'] + '-d', 'core.NullDereference', + '-d', 'clang-diagnostic'] ret = codechecker.log_and_analyze(codechecker_cfg, test_proj_path_base) if ret: @@ -95,7 +96,8 @@ def setup_class(self): codechecker_cfg['reportdir'] = os.path.join(test_proj_path_new, 'reports') codechecker_cfg['checkers'] = ['-d', 'core.CallAndMessage', - '-e', 'core.NullDereference'] + '-e', 'core.NullDereference', + '-d', 'clang-diagnostic'] ret = codechecker.log_and_analyze(codechecker_cfg, test_proj_path_new) if ret: diff --git a/web/tests/functional/report_viewer_api/__init__.py b/web/tests/functional/report_viewer_api/__init__.py index fb22cc68a0..6e35d8b47e 100644 --- a/web/tests/functional/report_viewer_api/__init__.py +++ b/web/tests/functional/report_viewer_api/__init__.py @@ -24,7 +24,18 @@ def setup_class_common(workspace_name): - """Setup the environment for the tests.""" + """ + Setup the environment for the tests. + + This test suite analyzes and stores a sample project with different + configurations in different runs and tags. The test cases are observing the + effect of configurations by checking the number of results. The number of + reports by checkers are commented above the specific configurations so it + is easier to see the content of the current analysis. + + There is no concept behind which checkers are enabled or disabled during an + analysis. The point is that the result sets are different in the runs. + """ global TEST_WORKSPACE TEST_WORKSPACE = env.get_workspace(workspace_name) @@ -52,12 +63,29 @@ def setup_class_common(workspace_name): test_env = env.test_env(TEST_WORKSPACE) + # ----------------------------------------------------- + # Checker name | Number of reports + # ----------------------------------------------------- + # clang-diagnostic-division-by-zero | 3 + # clang-diagnostic-return-type | 5 + # core.CallAndMessage | 5 + # core.DivideZero | 10 + # core.NullDereference | 4 + # core.StackAddressEscape | 3 + # cplusplus.NewDelete | 5 + # deadcode.DeadStores | 6 + # misc-definitions-in-headers | 2 + # unix.Malloc | 1 + # ----------------------------------------------------- + codechecker_cfg = { 'suppress_file': suppress_file, 'skip_list_file': skip_list_file, 'check_env': test_env, 'workspace': TEST_WORKSPACE, - 'checkers': ['-e', 'clang-diagnostic-return-type'], + 'checkers': ['-d', 'clang-diagnostic', + '-e', 'clang-diagnostic-division-by-zero', + '-e', 'clang-diagnostic-return-type'], 'tag': tag, 'analyzers': ['clangsa', 'clang-tidy'] } @@ -87,11 +115,25 @@ def setup_class_common(workspace_name): test_project_name_new = project_info['name'] + '*' + uuid.uuid4().hex + '%' + # ----------------------------------------------------- + # Checker name | Number of reports + # ----------------------------------------------------- + # clang-diagnostic-division-by-zero | 3 + # core.CallAndMessage | 5 + # core.DivideZero | 10 + # core.NullDereference | 4 + # cplusplus.NewDelete | 5 + # deadcode.DeadStores | 6 + # misc-definitions-in-headers | 2 + # ----------------------------------------------------- + # Let's run the second analysis with different # checkers to have some real difference. codechecker_cfg['checkers'] = ['-e', 'core.CallAndMessage', '-d', 'core.StackAddressEscape', - '-d', 'unix.Malloc' + '-d', 'unix.Malloc', + '-d', 'clang-diagnostic', + '-e', 'clang-diagnostic-division-by-zero' ] codechecker_cfg['tag'] = None ret = codechecker.check_and_store(codechecker_cfg, @@ -104,6 +146,19 @@ def setup_class_common(workspace_name): test_project_name_third = project_info['name'] + uuid.uuid4().hex + # ----------------------------------------------------- + # Checker name | Number of reports + # ----------------------------------------------------- + # clang-diagnostic-division-by-zero | 3 + # core.CallAndMessage | 5 + # core.DivideZero | 10 + # core.NullDereference | 4 + # cplusplus.NewDelete | 5 + # deadcode.DeadStores | 6 + # misc-definitions-in-headers | 2 + # unix.Malloc | 1 + # ----------------------------------------------------- + # Let's run the third analysis. ret = codechecker.check_and_store(codechecker_cfg, test_project_name_third, @@ -113,8 +168,24 @@ def setup_class_common(workspace_name): sys.exit(1) print("Third analysis of the test project was successful.") + # ----------------------------------------------------- + # Checker name | Number of reports + # ----------------------------------------------------- + # clang-diagnostic-division-by-zero | 3 + # clang-diagnostic-return-type | 5 + # core.CallAndMessage | 5 + # core.DivideZero | 10 + # core.NullDereference | 4 + # cplusplus.NewDelete | 5 + # deadcode.DeadStores | 6 + # misc-definitions-in-headers | 2 + # ----------------------------------------------------- + # Let's run the second analysis and updat the same run. - codechecker_cfg['checkers'] = ['-d', 'core.StackAddressEscape'] + codechecker_cfg['checkers'] = ['-d', 'core.StackAddressEscape', + '-d', 'clang-diagnostic', + '-e', 'clang-diagnostic-division-by-zero', + '-e', 'clang-diagnostic-return-type'] ret = codechecker.check_and_store(codechecker_cfg, test_project_name_third, project.path(test_project)) diff --git a/web/tests/functional/source_change/test_source_change.py b/web/tests/functional/source_change/test_source_change.py index 3e6ce8a4a0..afd21f0640 100644 --- a/web/tests/functional/source_change/test_source_change.py +++ b/web/tests/functional/source_change/test_source_change.py @@ -74,7 +74,7 @@ def setup_class(self): 'workspace': TEST_WORKSPACE, 'reportdir': os.path.join(TEST_WORKSPACE, 'reports'), 'checkers': [], - 'analyzers': ['clangsa', 'clang-tidy'] + 'analyzers': ['clangsa'] } # Start or connect to the running CodeChecker server and get connection From 2c5a326afe8f7b44d310698b58fca1dc4bc036e3 Mon Sep 17 00:00:00 2001 From: bruntib Date: Mon, 10 Jul 2023 12:54:32 +0200 Subject: [PATCH 3/3] [feat] Hide disabled ClangSA checkers in post-processing ClangSA checkers may rely on each other. For example unix.Malloc checker may prevent a report from unix.MismatchedDeallocator. It is possible that after disabling unix.Malloc the underlying analysis continues giving a chance for unix.MismatchedDeallocator to emit a report. In order to avoid this noisy behavior, ClangSA checkers are never disabled during the analysis invocation. If CodeChecker wants to disable a checker then its result should be hidden in a post-processing step. --- .../analyzers/clangsa/analyzer.py | 47 ++++++++++++++++--- .../analyzers/result_handler_base.py | 6 +-- analyzer/tests/unit/test_checker_handling.py | 12 ++--- .../functional/report_viewer_api/__init__.py | 6 +++ .../report_viewer_api/test_report_counting.py | 9 ++-- .../report_viewer_api/test_report_filter.py | 4 +- 6 files changed, 59 insertions(+), 25 deletions(-) diff --git a/analyzer/codechecker_analyzer/analyzers/clangsa/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangsa/analyzer.py index 2aa451ec38..73f0118e94 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangsa/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangsa/analyzer.py @@ -10,6 +10,7 @@ """ import os +import plistlib import re import shlex import subprocess @@ -123,6 +124,7 @@ def __init__(self, cfg_handler, buildaction): super(ClangSA, self).__init__(cfg_handler, buildaction) self.__disable_ctu = False self.__checker_configs = [] + self.__disabled_checkers = [] @classmethod def analyzer_binary(cls): @@ -305,6 +307,43 @@ def get_analyzer_config(cls) -> List[str]: return parse_clang_help_page(command, 'OPTIONS:') + def post_analyze(self, result_handler): + """ + Disabled checkers are not actually disabled during analysis, because + they might rely on each other under the hood. The disabled checkers' + reports are removed in this post-processing step. + """ + try: + if not os.path.isfile(result_handler.analyzer_result_file): + # This check has the same race-condition reason as the + # exception, so see its description below. + return + + with open(result_handler.analyzer_result_file, 'rb') as f: + plist = plistlib.load(f) + except plistlib.InvalidFileException: + # It may happen that a compilation database contains a build action + # multiple times (because it is compiled for several target + # architectures), or at least they differ in a so minor part that + # the same .plist file belongs to them. (For further details see + # analyzer_action_str() in ResultHandler about the strange behavior + # of make 4.3 in its -o flag.) + # If this happens then the analysis of the same build action is + # analyzed in parallel several times, so the same output .plist + # file is changed by several threads. This may result an invalid + # .plist which fails plistlib.load(). This is not a big problem, + # because the second thread will also execute this post-processing + # and it happens rarely anyways. test_compile_uniqueing() fails + # undeterministically without this. + return + + plist['diagnostics'] = list(filter( + lambda diag: diag['check_name'] not in self.__disabled_checkers, + plist.get('diagnostics', []))) + + with open(result_handler.analyzer_result_file, 'wb') as f: + plistlib.dump(plist, f) + def construct_analyzer_cmd(self, result_handler): """ Called by the analyzer method. @@ -356,23 +395,19 @@ def construct_analyzer_cmd(self, result_handler): ['-Xclang', '-analyzer-config', '-Xclang', cfg]) # Config handler stores which checkers are enabled or disabled. - disabled_checkers = [] + self.__disabled_checkers = [] enabled_checkers = [] for checker_name, value in config.checks().items(): state, _ = value if state == CheckerState.enabled: enabled_checkers.append(checker_name) elif state == CheckerState.disabled: - disabled_checkers.append(checker_name) + self.__disabled_checkers.append(checker_name) if enabled_checkers: analyzer_cmd.extend(['-Xclang', '-analyzer-checker=' + ','.join(enabled_checkers)]) - if disabled_checkers: - analyzer_cmd.extend(['-Xclang', - '-analyzer-disable-checker=' + - ','.join(disabled_checkers)]) # Enable aggressive-binary-operation-simplification option. version_info = ClangSA.version_info() if version_info and version_info.major_version >= 8: diff --git a/analyzer/codechecker_analyzer/analyzers/result_handler_base.py b/analyzer/codechecker_analyzer/analyzers/result_handler_base.py index bb4425c78c..d306ebe81e 100644 --- a/analyzer/codechecker_analyzer/analyzers/result_handler_base.py +++ b/analyzer/codechecker_analyzer/analyzers/result_handler_base.py @@ -114,9 +114,9 @@ def analyzer_action_str(self): # build command, because its hash is used for identification in the # plist file name. # - # TODO: This solution is considered a workaround, because the real - # question is why such a subprocess is logged? Can cc1build be always - # used as a traditional g++ command? + # The proper logging of this "make 4.3" version has been done in + # bf140d6, so it is unlikely happen that two build actions differ only + # in their "-o" flags. This workaround is still kept for any case. # # Note that some information loss occurs during the following algorithm # because ' '.join(shlex.split(cmd)) is not necessarily equal to cmd: diff --git a/analyzer/tests/unit/test_checker_handling.py b/analyzer/tests/unit/test_checker_handling.py index e2145cc5c3..19824cbffd 100644 --- a/analyzer/tests/unit/test_checker_handling.py +++ b/analyzer/tests/unit/test_checker_handling.py @@ -111,15 +111,9 @@ def test_no_disabled_checks(self): """ Test that ClangSA only uses enable lists. """ - # TODO: This test is currently removed, because checkers that are not - # enabled are explicitly disabled. In a next commit ClangSA reports - # will be hidden instead of disabled. In that commit this test could be - # re-enabled. - pass - - # self.assertFalse( - # any(arg.startswith('-analyzer-disable-checker') - # for arg in self.__class__.cmd)) + self.assertFalse( + any(arg.startswith('-analyzer-disable-checker') + for arg in self.__class__.cmd)) def test_checker_initializer(self): """ diff --git a/web/tests/functional/report_viewer_api/__init__.py b/web/tests/functional/report_viewer_api/__init__.py index 6e35d8b47e..8d8e6ce41d 100644 --- a/web/tests/functional/report_viewer_api/__init__.py +++ b/web/tests/functional/report_viewer_api/__init__.py @@ -160,6 +160,11 @@ def setup_class_common(workspace_name): # ----------------------------------------------------- # Let's run the third analysis. + codechecker_cfg['checkers'] = ['-e', 'core.CallAndMessage', + '-d', 'core.StackAddressEscape', + '-d', 'clang-diagnostic', + '-e', 'clang-diagnostic-division-by-zero' + ] ret = codechecker.check_and_store(codechecker_cfg, test_project_name_third, project.path(test_project)) @@ -183,6 +188,7 @@ def setup_class_common(workspace_name): # Let's run the second analysis and updat the same run. codechecker_cfg['checkers'] = ['-d', 'core.StackAddressEscape', + '-d', 'unix.Malloc', '-d', 'clang-diagnostic', '-e', 'clang-diagnostic-division-by-zero', '-e', 'clang-diagnostic-return-type'] diff --git a/web/tests/functional/report_viewer_api/test_report_counting.py b/web/tests/functional/report_viewer_api/test_report_counting.py index 475fe5db23..4889e83fe3 100644 --- a/web/tests/functional/report_viewer_api/test_report_counting.py +++ b/web/tests/functional/report_viewer_api/test_report_counting.py @@ -88,14 +88,13 @@ def setup_method(self, method): 'core.NullDereference': 4, 'cplusplus.NewDelete': 5, 'deadcode.DeadStores': 6, - 'misc-definitions-in-headers': 2, - 'unix.MismatchedDeallocator': 1} + 'misc-definitions-in-headers': 2} self.run1_sev_counts = {Severity.MEDIUM: 6, Severity.LOW: 6, Severity.HIGH: 32} - self.run2_sev_counts = {Severity.MEDIUM: 6, + self.run2_sev_counts = {Severity.MEDIUM: 5, Severity.LOW: 6, Severity.HIGH: 24} @@ -103,7 +102,7 @@ def setup_method(self, method): {DetectionStatus.NEW: 44} self.run2_detection_counts = \ - {DetectionStatus.NEW: 36} + {DetectionStatus.NEW: 35} self.run1_files = \ {'new_delete.cpp': 6, @@ -125,7 +124,7 @@ def setup_method(self, method): self.run2_files = \ {'call_and_message.cpp': 5, - 'new_delete.cpp': 6, + 'new_delete.cpp': 5, 'divide_zero.cpp': 5, 'divide_zero_duplicate.cpp': 2, 'null_dereference.cpp': 5, diff --git a/web/tests/functional/report_viewer_api/test_report_filter.py b/web/tests/functional/report_viewer_api/test_report_filter.py index 2c5ac10a38..d46fc3f473 100644 --- a/web/tests/functional/report_viewer_api/test_report_filter.py +++ b/web/tests/functional/report_viewer_api/test_report_filter.py @@ -220,7 +220,7 @@ def test_run1_run2_all_results(self): ReportFilter(), None) - self.assertEqual(run_result_count, 80) + self.assertEqual(run_result_count, 79) run_results = self._cc_client.getRunResults(self._runids, run_result_count, @@ -382,7 +382,7 @@ def test_detection_date_filters(self): def test_fix_date_filters(self): """ Filter by fix dates. """ report_filter = ReportFilter( - detectionStatus=[DetectionStatus.RESOLVED]) + detectionStatus=[DetectionStatus.OFF]) run_results = self._cc_client.getRunResults(None, None, 0, None, report_filter, None, False)