diff --git a/analyzer/codechecker_analyzer/analyzers/clangsa/result_handler.py b/analyzer/codechecker_analyzer/analyzers/clangsa/result_handler.py index 73954ab52b..ae31456688 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangsa/result_handler.py +++ b/analyzer/codechecker_analyzer/analyzers/clangsa/result_handler.py @@ -26,5 +26,5 @@ def postprocess_result(self): Override the context sensitive issue hash in the plist files to context insensitive if it is enabled during analysis. """ - if self.report_hash_type == 'context-free': + if self.report_hash_type in ['context-free', 'context-free-v2']: report.use_context_free_hashes(self.analyzer_result_file) diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py index 612937946d..65a76c2b30 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/analyzer.py @@ -238,6 +238,8 @@ def construct_config_handler(cls, args, context): handler = config_handler.ClangTidyConfigHandler() handler.analyzer_binary = context.analyzer_binaries.get( cls.ANALYZER_NAME) + handler.report_hash = args.report_hash \ + if 'report_hash' in args else None # FIXME We cannot get the resource dir from the clang-tidy binary, # therefore we get a sibling clang binary which of clang-tidy. diff --git a/analyzer/codechecker_analyzer/analyzers/clangtidy/result_handler.py b/analyzer/codechecker_analyzer/analyzers/clangtidy/result_handler.py index 4aaea18a5e..92358c0c5a 100644 --- a/analyzer/codechecker_analyzer/analyzers/clangtidy/result_handler.py +++ b/analyzer/codechecker_analyzer/analyzers/clangtidy/result_handler.py @@ -47,5 +47,11 @@ def postprocess_result(self): tidy_stdout = self.analyzer_stdout.splitlines() generate_plist_from_tidy_result(output_file, tidy_stdout) - if self.report_hash_type == 'context-free': + # In the earlier versions of CodeChecker Clang Tidy never used context + # free hash even if we enabled it with '--report-hash context-free' + # when calling the analyze command. To do not break every hash + # automatically when using this option we introduced a new choice for + # --report-hash option ('context-free-v2') and we still do not use + # context free hash for 'context-free' choice. + if self.report_hash_type == 'context-free-v2': report.use_context_free_hashes(output_file) diff --git a/analyzer/codechecker_analyzer/arg.py b/analyzer/codechecker_analyzer/arg.py index 8f9237dac7..836ceea93e 100644 --- a/analyzer/codechecker_analyzer/arg.py +++ b/analyzer/codechecker_analyzer/arg.py @@ -7,6 +7,7 @@ import argparse +import textwrap class RawDescriptionDefaultHelpFormatter( @@ -17,7 +18,20 @@ class RawDescriptionDefaultHelpFormatter( Adds default values to argument help and retains any formatting in descriptions. """ - pass + def _split_lines(self, text, width): + """ Split the lines. + + If the text parameter starts with 'R|' it will keep whitespaces and + it will wrapp the content. Otherwise it will call the parent function + of RawDescriptionHelpFormatter. + """ + if text.startswith('R|'): + lines = [textwrap.wrap(line, width, replace_whitespace=False) + for line in text[2:].lstrip().splitlines()] + return [line for sublines in lines for line in sublines] + + return argparse.RawDescriptionHelpFormatter._split_lines(self, text, + width) class OrderedCheckersAction(argparse.Action): diff --git a/analyzer/codechecker_analyzer/cmd/analyze.py b/analyzer/codechecker_analyzer/cmd/analyze.py index 3e7bf95b1d..cf2c01846e 100644 --- a/analyzer/codechecker_analyzer/cmd/analyze.py +++ b/analyzer/codechecker_analyzer/cmd/analyze.py @@ -203,16 +203,18 @@ def add_arguments_to_parser(parser): dest="report_hash", default=argparse.SUPPRESS, required=False, - choices=['context-free'], - help="Specify the hash calculation method for " - "reports. If this option is not set, the default " - "calculation method for Clang Static Analyzer " - "will be context sensitive and for Clang Tidy it " - "will be context insensitive. If this option is " - "set to 'context-free' bugs will be identified " - "with the CodeChecker generated context free " - "hash for every analyzers. USE WISELY AND AT " - "YOUR OWN RISK!") + choices=['context-free', 'context-free-v2'], + help="R|Specify the hash calculation method for " + "reports. By default the calculation method for " + "Clang Static Analyzer is context sensitive and " + "for Clang Tidy it is context insensitive.\n" + "You can use the following calculation methods:\n" + "- context-free: there was a bug and for Clang " + "Tidy not the context free hash was generated " + "(kept for backward compatibility).\n" + "- context-free-v2: context free hash is used " + "for ClangSA and Clang Tidy.\n" + "USE WISELY AND AT YOUR OWN RISK!") parser.add_argument('-n', '--name', dest="name", diff --git a/analyzer/codechecker_analyzer/cmd/check.py b/analyzer/codechecker_analyzer/cmd/check.py index 0bcbfa5548..1130969e53 100644 --- a/analyzer/codechecker_analyzer/cmd/check.py +++ b/analyzer/codechecker_analyzer/cmd/check.py @@ -213,18 +213,20 @@ def add_arguments_to_parser(parser): dest="report_hash", default=argparse.SUPPRESS, required=False, - choices=['context-free'], - help="Specify the hash calculation method for " - "reports. If this option is not set, the " - "default calculation method for Clang " - "Static Analyzer will be context " - "sensitive and for Clang Tidy it will be " - "context insensitive. If this option is " - "set to 'context-free' bugs will be " - "identified with the CodeChecker " - "generated context free hash for every " - "analyzers. USE WISELY AND AT YOUR OWN " - "RISK!") + choices=['context-free', 'context-free-v2'], + help="R|Specify the hash calculation method " + "for reports. By default the calculation " + "method for Clang Static Analyzer is " + "context sensitive and for Clang Tidy it " + "is context insensitive.\nYou can use the " + "following calculation methods:\n" + "- context-free: there was a bug and for " + "Clang Tidy not the context free hash " + "was generated (kept for backward " + "compatibility).\n" + "- context-free-v2: context free hash is " + "used for ClangSA and Clang Tidy.\n" + "USE WISELY AND AT YOUR OWN RISK!") skip_mode = analyzer_opts.add_mutually_exclusive_group() skip_mode.add_argument('-i', '--ignore', '--skip', 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 new file mode 100644 index 0000000000..444be9df18 --- /dev/null +++ b/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_v2_clang_tidy.output @@ -0,0 +1,57 @@ +NORMAL#CodeChecker log --output $LOGFILE$ --build "make context_hash" --quiet +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --report-hash=context-free-v2 --analyzer clang-tidy +NORMAL#CodeChecker parse $OUTPUT$ --print-steps +CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --report-hash=context-free-v2 --analyzer clang-tidy +-------------------------------------------------------------------------------- +[] - Starting build ... +[] - Build finished successfully. +[] - Starting static analysis ... +[] - [1/1] clang-tidy analyzed context_hash.cpp successfully. +[] - ----==== Summary ====---- +[] - Successfully analyzed +[] - clang-tidy: 1 +[] - Total analyzed compilation commands: 1 +[] - ----=================---- +[] - Analysis finished. +[] - To view results in the terminal use the "CodeChecker parse" command. +[] - To store results use the "CodeChecker store" command. +[] - See --help and the user guide for further options about parsing and storing the reports. +[] - ----=================---- +[HIGH] context_hash.cpp:23:23: suspicious usage of 'sizeof(K)'; did you mean 'K'? [bugprone-sizeof-expression] + std::memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int) + ^ + Report hash: 0f66553a0a3a129a00773b0e8ae42ca0 + Steps: + 1, context_hash.cpp:23:23: suspicious usage of 'sizeof(K)'; did you mean 'K'? + +[HIGH] context_hash.cpp:34:23: suspicious usage of 'sizeof(K)'; did you mean 'K'? [bugprone-sizeof-expression] + std::memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int) + ^ + Report hash: 0f66553a0a3a129a00773b0e8ae42ca0 + Steps: + 1, context_hash.cpp:34:23: suspicious usage of 'sizeof(K)'; did you mean 'K'? + +[HIGH] context_hash.cpp:37:21: suspicious usage of 'sizeof(K)'; did you mean 'K'? [bugprone-sizeof-expression] +std::memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int) + ^ + Report hash: 0f66553a0a3a129a00773b0e8ae42ca0 + Steps: + 1, context_hash.cpp:37:21: suspicious usage of 'sizeof(K)'; did you mean 'K'? + +Found 3 defect(s) in context_hash.cpp + + +----==== Summary ====---- +------------------------------- +Filename | Report count +------------------------------- +context_hash.cpp | 3 +------------------------------- +----------------------- +Severity | Report count +----------------------- +HIGH | 3 +----------------------- +----=================---- +Total number of reports: 3 +----=================---- diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_v2_clangsa.output b/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_v2_clangsa.output new file mode 100644 index 0000000000..4222c9ce13 --- /dev/null +++ b/analyzer/tests/functional/analyze_and_parse/test_files/context_free_hash_v2_clangsa.output @@ -0,0 +1,57 @@ +NORMAL#CodeChecker log --output $LOGFILE$ --build "make context_hash" --quiet +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --report-hash=context-free-v2 --analyzer clangsa +NORMAL#CodeChecker parse $OUTPUT$ --print-steps +CHECK#CodeChecker check --build "make context_hash" --output $OUTPUT$ --quiet --print-steps --report-hash=context-free-v2 --analyzer clangsa +-------------------------------------------------------------------------------- +[] - Starting build ... +[] - Build finished successfully. +[] - Starting static analysis ... +[] - [1/1] clangsa analyzed context_hash.cpp successfully. +[] - ----==== Summary ====---- +[] - Successfully analyzed +[] - clangsa: 1 +[] - Total analyzed compilation commands: 1 +[] - ----=================---- +[] - Analysis finished. +[] - To view results in the terminal use the "CodeChecker parse" command. +[] - To store results use the "CodeChecker store" command. +[] - See --help and the user guide for further options about parsing and storing the reports. +[] - ----=================---- +[LOW] context_hash.cpp:8:3: Value stored to 'x' is never read [deadcode.DeadStores] + x = 1; + ^ + Report hash: 956cdff9afc6a5eca5478e218da0a3b2 + Steps: + 1, context_hash.cpp:8:3: Value stored to 'x' is never read + +[LOW] context_hash.cpp:13:3: Value stored to 'x' is never read [deadcode.DeadStores] + x = 1; + ^ + Report hash: 956cdff9afc6a5eca5478e218da0a3b2 + Steps: + 1, context_hash.cpp:13:3: Value stored to 'x' is never read + +[LOW] context_hash.cpp:19:3: Value stored to 'z' is never read [deadcode.DeadStores] + z = 1; + ^ + Report hash: 44ca8d5f4072148d92cfc3af541f1588 + Steps: + 1, context_hash.cpp:19:3: Value stored to 'z' is never read + +Found 3 defect(s) in context_hash.cpp + + +----==== Summary ====---- +------------------------------- +Filename | Report count +------------------------------- +context_hash.cpp | 3 +------------------------------- +----------------------- +Severity | Report count +----------------------- +LOW | 3 +----------------------- +----=================---- +Total number of reports: 3 +----=================---- diff --git a/docs/analyzer/user_guide.md b/docs/analyzer/user_guide.md index c3bed69e19..d366cf2388 100644 --- a/docs/analyzer/user_guide.md +++ b/docs/analyzer/user_guide.md @@ -84,10 +84,11 @@ usage: CodeChecker check [-h] [-o OUTPUT_DIR] [-t {plist}] [-q] [-f] [--keep-gcc-include-fixed] [--keep-gcc-intrin] (-b COMMAND | -l LOGFILE) [-j JOBS] [-c] [--compile-uniqueing COMPILE_UNIQUEING] - [--report-hash {context-free}] + [--report-hash {context-free,context-free-v2}] [-i SKIPFILE | --file FILE [FILE ...]] [--analyzers ANALYZER [ANALYZER ...]] [--add-compiler-defaults] [--capture-analysis-output] + [--config CONFIG_FILE] [--saargs CLANGSA_ARGS_CFG_FILE] [--tidyargs TIDY_ARGS_CFG_FILE] [--tidy-config TIDY_CONFIG] [--timeout TIMEOUT] @@ -172,15 +173,18 @@ analyzer arguments: directory. (By default, CodeChecker would keep reports and overwrites only those files that were update by the current build command). - --report-hash {context-free} - Specify the hash calculation method for reports. If - this option is not set, the default calculation method - for Clang Static Analyzer will be context sensitive - and for Clang Tidy it will be context insensitive. If - this option is set to 'context-free' bugs will be - identified with the CodeChecker generated context free - hash for every analyzers. USE WISELY AND AT YOUR OWN - RISK! + --report-hash {context-free,context-free-v2} + Specify the hash calculation method for reports. By + default the calculation method for Clang Static + Analyzer is context sensitive and for Clang Tidy it is + context insensitive. + You can use the following calculation methods: + - context-free: there was a bug and for Clang Tidy not + the context free hash was generated (kept for backward + compatibility). + - context-free-v2: context free hash is used for + ClangSA and Clang Tidy. + USE WISELY AND AT YOUR OWN RISK! -i SKIPFILE, --ignore SKIPFILE, --skip SKIPFILE Path to the Skipfile dictating which project files should be omitted from analysis. Please consult the @@ -509,8 +513,8 @@ usage: CodeChecker analyze [-h] [-j JOBS] [--keep-gcc-include-fixed] [--keep-gcc-intrin] [-t {plist}] [-q] [-c] [--compile-uniqueing COMPILE_UNIQUEING] - [--report-hash {context-free}] [-n NAME] - [--analyzers ANALYZER [ANALYZER ...]] + [--report-hash {context-free,context-free-v2}] + [-n NAME] [--analyzers ANALYZER [ANALYZER ...]] [--add-compiler-defaults] [--capture-analysis-output] [--config CONFIG_FILE] [--saargs CLANGSA_ARGS_CFG_FILE] @@ -591,15 +595,17 @@ optional arguments: python regex. If more than one matches an error is given. The whole compilation action text is searched for match. (default: none) - --report-hash {context-free} - Specify the hash calculation method for reports. If - this option is not set, the default calculation method - for Clang Static Analyzer will be context sensitive - and for Clang Tidy it will be context insensitive. If - this option is set to 'context-free' bugs will be - identified with the CodeChecker generated context free - hash for every analyzers. USE WISELY AND AT YOUR OWN - RISK! +Specify the hash calculation method for reports. By + default the calculation method for Clang Static + Analyzer is context sensitive and for Clang Tidy it is + context insensitive. + You can use the following calculation methods: + - context-free: there was a bug and for Clang Tidy not + the context free hash was generated (kept for backward + compatibility). + - context-free-v2: context free hash is used for + ClangSA and Clang Tidy. + USE WISELY AND AT YOUR OWN RISK! -n NAME, --name NAME Annotate the run analysis with a custom name in the created metadata file. --verbose {info,debug,debug_analyzer}