diff --git a/.github/workflows/install-deps.sh b/.github/workflows/install-deps.sh index 37bf443384..224035b25c 100755 --- a/.github/workflows/install-deps.sh +++ b/.github/workflows/install-deps.sh @@ -17,7 +17,16 @@ sudo apt-get install \ libssl-dev \ clang-14 \ clang-tidy-14 \ - cppcheck + cppcheck + +# Source: https://fbinfer.com/docs/getting-started +VERSION=1.1.0; \ +curl -sSL "https://github.com/facebook/infer/releases/download/v$VERSION/infer-linux64-v$VERSION.tar.xz" \ +| sudo tar -C /opt -xJ && \ +sudo ln -s "/opt/infer-linux64-v$VERSION/bin/infer" /usr/local/bin/infer + +ldd --version +infer help --version sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-14 9999 sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 9999 diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index fb6d6f7d0b..2d350690bf 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -74,11 +74,20 @@ jobs: if: ${{ matrix.os == 'ubuntu-20.04' }} run: sudo apt-get update && sudo apt-get install g++-13 clang clang-tidy cppcheck + # https://github.com/facebook/infer/blob/main/docker/1.1.0/Dockerfile + run: + INFER_VERSION=v1.2.0; \ + cd /opt && \ + curl -sL \ + https://github.com/facebook/infer/releases/download/${INFER_VERSION}/infer-linux-x86_64-${INFER_VERSION}.tar.xz | \ + tar xJ && \ + rm -f /infer && \ + ln -s ${PWD}/infer-linux-x86_64-$INFER_VERSION /infer - name: "Install run-time dependencies (OSX)" if: ${{ matrix.os == 'macos-10.15' }} run: - brew install llvm cppcheck g++-13 + brew install llvm cppcheck g++-13 infer - name: "Install run-time dependencies (Windows)" if: ${{ matrix.os == 'windows-2019' }} diff --git a/analyzer/codechecker_analyzer/analyzers/analyzer_base.py b/analyzer/codechecker_analyzer/analyzers/analyzer_base.py index a510db4634..473b908338 100644 --- a/analyzer/codechecker_analyzer/analyzers/analyzer_base.py +++ b/analyzer/codechecker_analyzer/analyzers/analyzer_base.py @@ -102,7 +102,7 @@ def construct_result_handler(self, buildaction, report_output, """ raise NotImplementedError("Subclasses should implement this!") - def analyze(self, analyzer_cmd, res_handler, proc_callback=None): + def analyze(self, analyzer_cmd, res_handler, proc_callback=None, env=None): """ Run the analyzer. """ @@ -111,12 +111,17 @@ def analyze(self, analyzer_cmd, res_handler, proc_callback=None): LOG.debug_analyzer('\n%s', ' '.join([shlex.quote(x) for x in analyzer_cmd])) + if not env: + env = analyzer_context.get_context().get_env_for_bin( + analyzer_cmd[0]) + res_handler.analyzer_cmd = analyzer_cmd try: ret_code, stdout, stderr \ = SourceAnalyzer.run_proc(analyzer_cmd, res_handler.buildaction.directory, - proc_callback) + proc_callback, + env) res_handler.analyzer_returncode = ret_code res_handler.analyzer_stdout = stdout res_handler.analyzer_stderr = stderr @@ -140,7 +145,7 @@ def post_analyze(self, result_handler): """ @staticmethod - def run_proc(command, cwd=None, proc_callback=None): + def run_proc(command, cwd=None, proc_callback=None, env=None): """ Just run the given command and return the return code and the stdout and stderr outputs of the process. @@ -156,8 +161,6 @@ def signal_handler(signum, _): signal.signal(signal.SIGINT, signal_handler) - env = analyzer_context.get_context().get_env_for_bin(command[0]) - LOG.debug('\nexecuting:%s\n', command) LOG.debug('\nENV:\n') LOG.debug(env) diff --git a/analyzer/codechecker_analyzer/analyzers/analyzer_types.py b/analyzer/codechecker_analyzer/analyzers/analyzer_types.py index 130288c728..5ea6ee1404 100644 --- a/analyzer/codechecker_analyzer/analyzers/analyzer_types.py +++ b/analyzer/codechecker_analyzer/analyzers/analyzer_types.py @@ -25,13 +25,16 @@ from .clangsa.analyzer import ClangSA from .cppcheck.analyzer import Cppcheck from .gcc.analyzer import Gcc +from .infer.analyzer import Infer LOG = get_logger('analyzer') supported_analyzers = {ClangSA.ANALYZER_NAME: ClangSA, ClangTidy.ANALYZER_NAME: ClangTidy, Cppcheck.ANALYZER_NAME: Cppcheck, - Gcc.ANALYZER_NAME: Gcc} + Gcc.ANALYZER_NAME: Gcc, + Infer.ANALYZER_NAME: Infer + } def is_ctu_capable(): diff --git a/analyzer/codechecker_analyzer/analyzers/infer/LICENSE.txt b/analyzer/codechecker_analyzer/analyzers/infer/LICENSE.txt new file mode 100644 index 0000000000..264eac1052 --- /dev/null +++ b/analyzer/codechecker_analyzer/analyzers/infer/LICENSE.txt @@ -0,0 +1,24 @@ +MIT License + +Copyright (c) Facebook, Inc. and its affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +The following license is valid for descriptions.json file located in the +current directory (codechecker/analyzer/codechecker_analyzer/analyzers/infer/) \ No newline at end of file diff --git a/analyzer/codechecker_analyzer/analyzers/infer/__init__.py b/analyzer/codechecker_analyzer/analyzers/infer/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/analyzer/codechecker_analyzer/analyzers/infer/analyzer.py b/analyzer/codechecker_analyzer/analyzers/infer/analyzer.py new file mode 100644 index 0000000000..2c5e3a54ff --- /dev/null +++ b/analyzer/codechecker_analyzer/analyzers/infer/analyzer.py @@ -0,0 +1,250 @@ +# ------------------------------------------------------------------------- +# +# Part of the CodeChecker project, under the Apache License v2.0 with +# LLVM Exceptions. See LICENSE for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ------------------------------------------------------------------------- +""" +Module for Facebook Infer analyzer related methods +""" +from collections import defaultdict +# TODO distutils will be removed in python3.12 +import shlex +import subprocess +import json +from pathlib import Path + +from codechecker_common.logger import get_logger + +from codechecker_analyzer import analyzer_context + +from .. import analyzer_base +from ..config_handler import CheckerState + +from .config_handler import InferConfigHandler +from .result_handler import InferResultHandler +from codechecker_analyzer.buildlog.log_parser import IGNORED_OPTIONS_GCC + +LOG = get_logger('analyzer.infer') + + +class Infer(analyzer_base.SourceAnalyzer): + """ + Constructs the Infer analyzer commands. + """ + + ANALYZER_NAME = 'infer' + + @classmethod + def analyzer_binary(cls): + return analyzer_context.get_context() \ + .analyzer_binaries[cls.ANALYZER_NAME] + + def add_checker_config(self, checker_cfg): + # TODO + pass + + def get_analyzer_mentioned_files(self, output): + """ + This is mostly used for CTU. + """ + return set() + + def construct_analyzer_cmd(self, result_handler): + """ + Construct analyzer command for Infer. + """ + # TODO: This is not a try-catch block, like the other analyzers. Why + # should it? Should the others be? When can list creating list to have + # unforeseen exceptions where a general catch is justified? + config = self.config_handler + + analyzer_cmd = [Infer.analyzer_binary(), 'run', '--keep-going', + '--project-root', '/'] + + for checker_name, value in config.checks().items(): + filtered_name = checker_name.replace("infer-", "") + filtered_name = filtered_name.replace("-", "_") + filtered_name = filtered_name.upper() + + if value[0] == CheckerState.DISABLED: + analyzer_cmd.extend(['--disable-issue-type', filtered_name]) + else: + analyzer_cmd.extend(['--enable-issue-type', filtered_name]) + + output_dir = Path(result_handler.workspace, "infer", + result_handler.buildaction_hash) + output_dir.mkdir(exist_ok=True, parents=True) + analyzer_cmd.extend(['-o', str(output_dir)]) + analyzer_cmd.append('--') + + cmd_filtered = [] + for cmd in shlex.split(self.buildaction.original_command): + if IGNORED_OPTIONS_GCC.match(cmd) and \ + self.buildaction.lang in ['c', 'c++']: + continue + cmd_filtered.append(cmd) + + if self.buildaction.lang == 'c++': + cmd_filtered.append('-stdlib=libc++') + + analyzer_cmd.extend(cmd_filtered) + LOG.debug_analyzer("Running analysis command " + f"'{shlex.join(analyzer_cmd)}'") + + return analyzer_cmd + + @classmethod + def get_analyzer_checkers(cls): + """ + Return the list of the supported checkers. + """ + command = [cls.analyzer_binary(), "help", "--list-issue-types"] + desc = json.load( + open(Path(__file__).parent / "descriptions.json", + "r", encoding="utf-8")) + checker_list = [] + try: + env = analyzer_context.get_context().get_env_for_bin( + cls.analyzer_binary()) + env.update(TZ='UTC') + output = subprocess.check_output(command, + stderr=subprocess.DEVNULL, + env=env) + for entry in output.decode().split('\n'): + data = entry.strip().split(":") + if len(data) < 7: + continue + + entry_id = data[0].lower() + if entry_id in desc: + description = desc[entry_id] + else: + checker = data[6] if len(data) == 7 else data[5] + description = f"used by '{checker}' checker" + + entry_id = entry_id.replace("_", "-") + checker_list.append((f"infer-{entry_id}", + description)) + return checker_list + except (subprocess.CalledProcessError) as e: + LOG.error(e.stderr) + except (OSError) as e: + LOG.error(e.errno) + return [] + + @classmethod + def get_analyzer_config(cls): + """ + Config options for infer. + """ + return [] + + @classmethod + def get_checker_config(cls): + """ + Config options for infer checkers. + """ + return [] + + def analyze(self, analyzer_cmd, res_handler, proc_callback=None, env=None): + + env = analyzer_context.get_context().get_env_for_bin( + analyzer_cmd[0]) + env.update(TZ='UTC') + + result_handler = super().analyze( + analyzer_cmd, res_handler, proc_callback, env) + + if result_handler.analyzer_returncode != 0: + LOG.error(result_handler.analyzer_stderr) + + return result_handler + + def post_analyze(self, result_handler: InferResultHandler): + """ + Post process the results after the analysis. + """ + + @classmethod + def resolve_missing_binary(cls, configured_binary, environ): + """ + In case of the configured binary for the analyzer is not found in the + PATH, this method is used to find a callable binary. + """ + + @classmethod + def get_binary_version(cls, details=False) -> str: + """ + Return the analyzer version. + """ + # No need to LOG here, we will emit a warning later anyway. + if not cls.analyzer_binary(): + return None + version = [cls.analyzer_binary(), '--version'] + environ = analyzer_context.get_context().get_env_for_bin( + cls.analyzer_binary()) + environ.update(TZ='UTC') + try: + output = subprocess.check_output(version, + env=environ, + encoding="utf-8", + errors="ignore") + output = output.split('\n', maxsplit=1)[0] + return output.strip().split(" ")[-1][1:] + except (subprocess.CalledProcessError, OSError) as oerr: + LOG.warning("Failed to get analyzer version: %s", + ' '.join(version)) + LOG.warning(oerr) + return None + + @classmethod + def is_binary_version_incompatible(cls): + """ + Check the version compatibility of the given analyzer binary. + """ + return None + + def construct_result_handler(self, buildaction, report_output, + skiplist_handler): + """ + See base class for docs. + """ + res_handler = InferResultHandler(buildaction, report_output, + self.config_handler.report_hash) + + res_handler.skiplist_handler = skiplist_handler + + return res_handler + + @classmethod + def construct_config_handler(cls, args): + handler = InferConfigHandler() + + analyzer_config = defaultdict(list) + + if 'analyzer_config' in args and \ + isinstance(args.analyzer_config, list): + for cfg in args.analyzer_config: + if cfg.analyzer == cls.ANALYZER_NAME: + analyzer_config[cfg.option].append(cfg.value) + + handler.analyzer_config = analyzer_config + + checkers = cls.get_analyzer_checkers() + + try: + cmdline_checkers = args.ordered_checkers + except AttributeError: + LOG.debug_analyzer('No checkers were defined in ' + 'the command line for %s', + cls.ANALYZER_NAME) + cmdline_checkers = [] + + handler.initialize_checkers( + checkers, + cmdline_checkers, + 'enable_all' in args and args.enable_all) + + return handler diff --git a/analyzer/codechecker_analyzer/analyzers/infer/config_handler.py b/analyzer/codechecker_analyzer/analyzers/infer/config_handler.py new file mode 100644 index 0000000000..757ed19dc4 --- /dev/null +++ b/analyzer/codechecker_analyzer/analyzers/infer/config_handler.py @@ -0,0 +1,17 @@ +# ------------------------------------------------------------------------- +# +# Part of the CodeChecker project, under the Apache License v2.0 with +# LLVM Exceptions. See LICENSE for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ------------------------------------------------------------------------- +""" +Config handler for Infer analyzer. +""" +from .. import config_handler + + +class InferConfigHandler(config_handler.AnalyzerConfigHandler): + """ + Configuration handler for Infer analyzer. + """ diff --git a/analyzer/codechecker_analyzer/analyzers/infer/descriptions.json b/analyzer/codechecker_analyzer/analyzers/infer/descriptions.json new file mode 100644 index 0000000000..0a9bafd750 --- /dev/null +++ b/analyzer/codechecker_analyzer/analyzers/infer/descriptions.json @@ -0,0 +1,200 @@ +{ + "arbitrary_code_execution_under_lock": "A call that may execute arbitrary code (such as registered, or chained, callbacks) is made while holding a lock. This code may deadlock whenever the callbacks obtain locks themselves, so it is an unsafe pattern.", + "bad_arg": "Bad arg in Erlang: Reports an error when the type of an argument is wrong or the argument is badly formed. Corresponds to the badarg error in the Erlang runtime.", + "bad_arg_latent": "A latent BAD_ARG. See the documentation on Pulse latent issues.", + "bad_generator": "Bad generator in Erlang: Reports an error when a wrong type is used in a generator. Corresponds to the bad_generator error in the Erlang runtime.", + "bad_generator_latent": "A latent BAD_GENERATOR. See the documentation on Pulse latent issues.", + "bad_key": "Bad key in Erlang: Reports an error when trying to access or update a non-existing key in a map. Corresponds to the {badkey,K} error in the Erlang runtime.", + "bad_key_latent": "A latent BAD_KEY. See the documentation on Pulse latent issues.", + "bad_map": "Bad map in Erlang: Reports an error when trying to access or update a key for a term that is not a map. Corresponds to the {badmap,...} error in the Erlang runtime.", + "bad_map_latent": "A latent BAD_MAP. See the documentation on Pulse latent issues.", + "bad_record": "Bad record in Erlang: Reports an error when trying to access or update a record with the wrong name. Corresponds to the {badrecord,Name} error in the Erlang runtime.", + "bad_record_latent": "A latent BAD_RECORD. See the documentation on Pulse latent issues.", + "bad_return": "Bad return in Erlang: The dynamic type of a returned value disagrees with the static type given in the spec.", + "bad_return_latent": "A latent BAD_RETURN. See the documentation on Pulse latent issues.", + "biabduction_memory_leak": "See MEMORY_LEAK_C.", + "biabduction_retain_cycle": "See RETAIN_CYCLE.", + "block_parameter_not_null_checked": "This error type is reported only in Objective-C/Objective-C++. It happens when a method has a block as a parameter, and the block is executed in the method's body without checking it for nil first. If a nil block is passed to the method, then this will cause a crash. For example:", + "buffer_overrun_l1": "This is reported when outside of buffer bound is accessed. It can corrupt memory and may introduce security issues in C/C++.", + "buffer_overrun_l2": "See BUFFER_OVERRUN_L1", + "buffer_overrun_l3": "See BUFFER_OVERRUN_L1", + "buffer_overrun_l4": "See BUFFER_OVERRUN_L1", + "buffer_overrun_l5": "See BUFFER_OVERRUN_L1", + "buffer_overrun_s2": "See BUFFER_OVERRUN_L1", + "buffer_overrun_u5": "See BUFFER_OVERRUN_L1", + "captured_strong_self": "This check is about when a strong pointer to self is captured in a block. This could lead to retain cycles or unexpected behavior since to avoid retain cycles one usually uses a local strong pointer or a captured weak pointer instead.", + "checkers_allocates_memory": "A method annotated with @NoAllocation transitively calls new.", + "checkers_annotation_reachability_error": "A method annotated with an annotation @A transitively calls a method annotated @B where the combination of annotations is forbidden (for example, @UiThread calling @WorkerThread).", + "checkers_calls_expensive_method": "A method annotated with @PerformanceCritical transitively calls a method annotated @Expensive.", + "checkers_expensive_overrides_unannotated": "A method annotated with @Expensive overrides an un-annotated method.", + "checkers_fragment_retains_view": "This error type is Android-specific. It fires when a Fragment type fails to nullify one or more of its declared View fields in onDestroyView. In performance-sensitive applications, a Fragment should initialize all View's in onCreateView and nullify them in onDestroyView. If a Fragment is placed on the back stack and fails to nullify a View in onDestroyView, it will retain a useless reference to that View that will not be cleaned up until the Fragment is resumed or destroyed.", + "checkers_printf_args": "This error is reported when the argument types to a printf method do not match the format string.", + "config_impact": "Infer reports this issue when an expensive function is called without a config check. The config is usually a boolean value that enables experimental new features and it is defined per application/codebase, e.g. gatekeepers. To determine whether a function is expensive or not, the checker relies on modeled functions that are assumed to be expensive, e.g. string operations, regular expression match, or DB accesses.", + "config_impact_strict": "This is similar to CONFIG_IMPACT issue but the analysis reports all ungated codes irrespective of whether they are expensive or not.", + "config_usage": "Infer reports this issue when a config value is used as branch condition in a function. The config is usually a boolean value that enables experimental new features and it is defined per application/codebase, e.g. gatekeepers.", + "constant_address_dereference": "This is reported when an address at an absolute location, e.g. 1234, is dereferenced. It is a more general version of the NULLPTR_DEREFERENCE error type that is reported when the address is a constant other than zero.", + "constant_address_dereference_latent": "A latent CONSTANT_ADDRESS_DEREFERENCE. See the documentation on Pulse latent issues.", + "create_intent_from_uri": "Create an intent/start a component using a (possibly user-controlled) URI. may or may not be an issue depending on where the URI comes from.", + "cross_site_scripting": "Untrusted data flows into HTML; XSS risk.", + "cxx_ref_captured_in_block": "This check flags when a C++ reference is captured in an escaping block. This means that the block will be leaving the current scope, i.e. it is not annotated with __attribute__((noescape)).", + "dangling_pointer_dereference": "DATALOG_FACT", + "datalog_fact": "Datalog fact used as input for a datalog solver.", + "data_flow_to_sink": "A flow of data was detected to a sink.", + "deadlock": "This error is currently reported in Java. A deadlock occurs when two distinct threads try to acquire two locks in reverse orders. The following code illustrates a textbook example. Of course, in real deadlocks, the lock acquisitions may be separated by deeply nested call chains.", + "dead_store": "This error is reported in C++. It fires when the value assigned to a variables is never used (e.g., int i = 1; i = 2; return i;).", + "divide_by_zero": "EMPTY_VECTOR_ACCESS", + "empty_vector_access": "This error type is reported only in C++, in versions >= C++11.", + "execution_time_complexity_increase": "Infer reports this issue when the execution time complexity of a program increases in degree: e.g. from constant to linear or from logarithmic to quadratic. This issue type is only reported in differential mode: i.e when we are comparing the cost analysis results of two runs of infer on a file. Check out examples in here.", + "execution_time_complexity_increase_ui_thread": "Infer reports this issue when the execution time complexity of the procedure increases in degree and the procedure runs on the UI (main) thread.", + "execution_time_unreachable_at_exit": "This issue type indicates that the program's execution doesn't reach the exit node (where our analysis computes the final cost of the procedure). Hence, we cannot compute a static bound for the procedure.", + "expensive_execution_time": "[EXPERIMENTAL] This warning indicates that the procedure has non-constant and non-top execution cost. By default, this issue type is disabled. To enable it, set enabled=true in costKind.ml.", + "expensive_loop_invariant_call": "We report this issue type when a function is loop-invariant and also expensive (i.e. at least has linear complexity as determined by the cost analysis).", + "exposed_insecure_intent_handling": "Undocumented.", + "guardedby_violation": "A field annotated with @GuardedBy is being accessed by a call-chain that starts at a non-private method without synchronization.", + "impure_function": "This issue type indicates impure functions. For instance, below functions would be marked as impure:", + "inefficient_keyset_iterator": "This issue is raised when", + "inferbo_alloc_is_big": "malloc is passed a large constant value (>=10^6). For example, int n = 1000000; malloc(n); generates INFERBO_ALLOC_IS_BIG on malloc(n).", + "inferbo_alloc_is_negative": "malloc is called with a negative size. For example, int n = 3 - 5; malloc(n); generates INFERBO_ALLOC_IS_NEGATIVE on malloc(n).", + "inferbo_alloc_is_zero": "malloc is called with a zero size. For example, int n = 3 - 3; malloc(n); generates INFERBO_ALLOC_IS_ZERO on malloc(n).", + "inferbo_alloc_may_be_big": "malloc may be called with a large value. For example, int n = b ? 3 : 1000000; malloc(n); generates INFERBO_ALLOC_MAY_BE_BIG on malloc(n).", + "inferbo_alloc_may_be_negative": "malloc may be called with a negative value. For example, int n = b ? 3 : -5; malloc(n); generates INFERBO_ALLOC_MAY_BE_NEGATIVE on malloc(n).", + "infinite_execution_time": "This warning indicates that Infer was not able to determine a static upper bound on the execution cost of the procedure. By default, this issue type is disabled.", + "example-1-t-due-to-expressivity": "For instance, Inferbo's interval analysis is limited to affine expressions. Hence, we can't statically estimate an upper bound on the below example and obtain T(unknown) cost:", + "example-2-t-due-to-unmodeled-calls": "Another common case where we get T cost is when Infer cannot statically determine the range of values for loop bounds. For instance,", + "example-3-t-due-to-calling-another-t-costed-function": "Since the analysis is inter-procedural, another example we can have T cost is if at least one of the callees has T cost.", + "insecure_intent_handling": "Undocumented.", + "integer_overflow_l1": "This is reported when integer overflow occurred by integer operations such as addition, subtraction, and multiplication. For example, int n = INT_MAX; int m = n + 3; generates a INTEGER_OVERFLOW_L1 on n + 3.", + "integer_overflow_l2": "See INTEGER_OVERFLOW_L1", + "integer_overflow_l5": "See INTEGER_OVERFLOW_L1", + "integer_overflow_u5": "See INTEGER_OVERFLOW_L1", + "interface_not_thread_safe": "This error indicates that you have invoked an interface method not annotated with @ThreadSafe from a thread-safe context (e.g., code that uses locks or is marked @ThreadSafe). The fix is to add the @ThreadSafe annotation to the interface or to the interface method. For background on why these annotations are needed, see the detailed explanation here.", + "invalid_sil": "The SIL instruction does not conform to the expected subset of instructions expected for the front-end of the language for the analyzed code.", + "invariant_call": "We report this issue type when a function call is loop-invariant and hoistable, i.e.", + "ipc_on_ui_thread": "A blocking Binder IPC call occurs on the UI thread.", + "javascript_injection": "Untrusted data flows into JavaScript.", + "lab_resource_leak": "Toy issue.", + "lockless_violation": "A method implements an interface signature annotated with @Lockless but which transitively acquires a lock.", + "lock_consistency_violation": "This is an error reported on C++ and Objective C classes whenever:", + "fixing-lock-consistency-violation-reports": "Avoid the offending access (most often the read). Of course, this may not be possible. Use synchronization to protect the read, by using the same lock protecting the corresponding write. Make the method doing the read access private. This should silence the warning, since Infer looks for a pair of non-private methods. Objective-C: Infer considers a method as private if it's not exported in the header-file interface.", + "logging_private_data": "Undocumented.", + "memory_leak_c": "Memory leak in C", + "memory-leak-in-c": "This error type is only reported in C and Objective-C code. In Java we do not report memory leaks because it is a garbage collected language.", + "memory-leak-in-objective-c": "Additionally, in Objective-C, Infer reports memory leaks that happen when objects from Core Foundation or Core Graphics don't get released.", + "memory_leak_cpp": "See MEMORY_LEAK_C", + "missing_required_prop": "This issues is reported when a required @Prop is missing.", + "examples": "Assume that the following Litho Component specification is defined as follows where prop1 is optional and prop2 is required.", + "mixed_self_weakself": "This check reports an issue when an Objective-C block captures both self and weakSelf, a weak pointer to self. Possibly the developer meant to capture only weakSelf to avoid a retain cycle, but made a typo and used self instead of strongSelf. In this case, this could cause a retain cycle.", + "modifies_immutable": "This issue type indicates modifications to fields marked as @Immutable. For instance, below function mutateArray would be marked as modifying immutable field testArray:", + "multiple_weakself": "This check reports when an Objective-C block uses weakSelf (a weak pointer to self) more than once. This could lead to unexpected behaviour. Even if weakSelf is not nil in the first use, it could be nil in the following uses since the object that weakSelf points to could be freed anytime.", + "mutual_recursion_cycle": "A recursive call or mutually recursive call has been detected. This does not mean that the program won't terminate, just that the code is recursive. You should double-check if the recursion is intended and if it can lead to non-termination or a stack overflow.", + "nil_block_call": "This check reports when one tries to call an Objective-C block that is nil. This causes a crash.", + "nil_block_call_latent": "A latent NIL_BLOCK_CALL. See the documentation on Pulse latent issues.", + "nil_insertion_into_collection": "This checks reports when nil is passed to collections in Objective-C such as arrays and dictionaries. This causes a crash.", + "arrays": "Adding objects to an array, inserting objects at a given index, or replacing objects at a given index, can all lead to a crash when the object is nil.", + "dictionaries": "Adding a nil value in a dictionary causes a crash. If the concept of nil is required, one can add [NSNull null] instead.", + "nil_insertion_into_collection_latent": "A latent NIL_INSERTION_INTO_COLLECTION. See the documentation on Pulse latent issues.", + "nil_messaging_to_non_pod": "In Objective-C, calling a method on nil (or in Objective-C terms, sending a message to nil) does not crash, it simply returns a falsy value (nil/0/false). However, sending a message that returns a non-POD C++ type (POD being \"Plain Old Data\", essentially anything that cannot be compiled as a C-style struct) to nil causes undefined behaviour.", + "nil_messaging_to_non_pod_latent": "A latent NIL_MESSAGING_TO_NON_POD. See the documentation on Pulse latent issues.", + "no_matching_branch_in_try": "No matching branch is found when evaluating the of section of a try expression. Corresponds to the {try_clause,V} error in the Erlang runtime.", + "no_matching_branch_in_try_latent": "A latent NO_MATCHING_BRANCH_IN_TRY. See the documentation on Pulse latent issues.", + "no_matching_case_clause": "No matching case clause in Erlang: Reports an error when none of the clauses of a case match the expression. Corresponds to the {case_clause,V} error in the Erlang runtime.", + "no_matching_case_clause_latent": "A latent NO_MATCHING_CASE_CLAUSE. See the documentation on Pulse latent issues.", + "no_matching_else_clause": "No matching else clause in Erlang: Reports an error when none of the clauses of an else match the short-circuit result from maybe body. Corresponds to the {else_clause,V} error in the Erlang runtime.", + "no_matching_else_clause_latent": "A latent NO_MATCHING_ELSE_CLAUSE. See the documentation on Pulse latent issues.", + "no_matching_function_clause": "No matching function clause in Erlang: Reports an error when none of the clauses of a function match the arguments of a call. Corresponds to the function_clause error in the Erlang runtime.", + "no_matching_function_clause_latent": "A latent NO_MATCHING_FUNCTION_CLAUSE. See the documentation on Pulse latent issues.", + "no_match_of_rhs": "No match of right hand side value in Erlang: Reports an error when the right hand side value of a match expression does not match the pattern on the left hand side. Corresponds to the {badmatch,V} error in the Erlang runtime.", + "no_match_of_rhs_latent": "A latent NO_MATCH_OF_RHS. See the documentation on Pulse latent issues.", + "no_true_branch_in_if": "No true branch when evaluating an if expression in Erlang: Reports an error when none of the branches of an if expression evaluate to true. Corresponds to the if_clause error in the Erlang runtime.", + "no_true_branch_in_if_latent": "A latent NO_TRUE_BRANCH_IN_IF. See the documentation on Pulse latent issues.", + "nullptr_dereference": "Infer reports null dereference bugs in Java, C, C++, and Objective-C when it is possible that the null pointer is dereferenced, leading to a crash.", + "null-dereference-in-java": "Many of Infer's reports of potential Null Pointer Exceptions (NPE) come from code of the form", + "null-dereference-in-c": "Here is an example of an inter-procedural null dereference bug in C:", + "null-dereference-in-objective-c": "In Objective-C, null dereferences are less common than in Java, but they still happen and their cause can be hidden. In general, passing a message to nil does not cause a crash and returns nil, but dereferencing a pointer directly does cause a crash.", + "nullptr_dereference_in_nullsafe_class": "Infer reports null dereference bugs in Java, C, C++, and Objective-C when it is possible that the null pointer is dereferenced, leading to a crash.", + "null-dereference-in-java-1": "Many of Infer's reports of potential Null Pointer Exceptions (NPE) come from code of the form", + "null-dereference-in-c-1": "Here is an example of an inter-procedural null dereference bug in C:", + "null-dereference-in-objective-c-1": "In Objective-C, null dereferences are less common than in Java, but they still happen and their cause can be hidden. In general, passing a message to nil does not cause a crash and returns nil, but dereferencing a pointer directly does cause a crash.", + "nullptr_dereference_in_nullsafe_class_latent": "A latent NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS. See the documentation on Pulse latent issues.", + "nullptr_dereference_latent": "A latent NULLPTR_DEREFERENCE. See the documentation on Pulse latent issues.", + "null_argument": "This issue type indicates `nil` being passed as argument where a non-nil value expected.", + "null_argument_latent": "A latent NULL_ARGUMENT. See the documentation on Pulse latent issues.", + "null_dereference": "See NULLPTR_DEREFERENCE.", + "optional_empty_access": "Optional Empty Access warnings are reported when we try to retrieve the value of a folly::Optional when it is empty (i.e. folly::none).", + "optional_empty_access_latent": "A latent OPTIONAL_EMPTY_ACCESS. See the documentation on Pulse latent issues.", + "premature_nil_termination_argument": "This error type is reported in C and Objective-C. In many variadic methods, nil is used to signify the end of the list of input objects. This is similar to nil-termination of C strings. If one of the arguments that is not the last argument to the method is nil as well, Infer reports an error because that may lead to unexpected behavior.", + "pulse_cannot_instantiate_abstract_class": "Instantiating an abstract class will lead to Cannot instantiate abstract class error.", + "pulse_const_refable": "This issue is reported when a function parameter is a) passed by value and b) is not modified inside the function. Instead, parameter can be passed by const reference, i.e. converted to a const& so that no unnecessary copy is created at the callsite of the function.", + "pulse_dict_missing_key": "This issue is similar to PULSE_UNINITIALIZED_VALUE, but it is to warn reading a missing key of dictionary in Hack.", + "pulse_dynamic_type_mismatch": "This error is reported in Hack. It fires when we detect an operation that is incompatible with the dynamic type of its arguments.", + "pulse_readonly_shared_ptr_param": "This issue is reported when a shared pointer parameter is a) passed by value and b) is used only for reading, rather than lifetime extension. At the callsite, this might cause a potentially expensive unnecessary copy of the shared pointer, especially when many number of threads are sharing it. To avoid this, consider 1) passing the raw pointer instead and 2) use std::shared_ptr::get at callsites.", + "pulse_reference_stability": "The family of maps folly::F14ValueMap, folly::F14VectorMap, and by extension folly::F14FastMap differs slightly from std::unordered_map as it does not provide reference stability. When the map resizes such as when reserve is called or new elements are added, all existing references become invalid and should not be used.", + "pulse_resource_leak": "See RESOURCE_LEAK", + "pulse_transitive_access": "This issue tracks spurious accesses that are reachable from specific entry functions.", + "pulse_unawaited_awaitable": "Awaitable values created by calls to asynchronous methods should eventually be awaited along all codepaths (even if their value is unused). Hence the following is not OK", + "pulse_uninitialized_const": "This issue is similar to PULSE_UNINITIALIZED_VALUE, but it is to detect the uninitialized abstract const value in Hack.", + "pulse_uninitialized_value": "The code uses a variable that has not been initialized, leading to unpredictable or unintended results.", + "pulse_unnecessary_copy": "This is reported when Infer detects an unnecessary copy of an object via copy constructor where neither the source nor the copied variable are modified before the variable goes out of scope. Rather than the copy, a reference to the source object could be used to save memory.", + "pulse_unnecessary_copy_assignment": "See PULSE_UNNECESSARY_COPY.", + "pulse_unnecessary_copy_assignment_const": "See PULSE_UNNECESSARY_COPY.", + "pulse_unnecessary_copy_assignment_movable": "See PULSE_UNNECESSARY_COPY_MOVABLE.", + "pulse_unnecessary_copy_intermediate": "This is reported when Infer detects an unnecessary temporary copy of an intermediate object where copy is created to be passed down to a function unnecessarily. Instead, the intermediate object should either be moved into the callee or the type of the callee's parameter should be made const &.", + "pulse_unnecessary_copy_intermediate_const": "See PULSE_UNNECESSARY_COPY.", + "pulse_unnecessary_copy_movable": "This is reported when Infer detects an unnecessary copy into a field where", + "pulse_unnecessary_copy_optional": "This is reported when Infer detects an unnecessary copy of an object via optional value construction where the source is not modified before it goes out of scope. To avoid the copy, we can move the source object or change the callee's type.", + "pulse_unnecessary_copy_optional_const": "See PULSE_UNNECESSARY_COPY_OPTIONAL.", + "pulse_unnecessary_copy_return": "This is similar to PULSE_UNNECESSARY_COPY, but reported when a callee returns a copied value and it is not modified in its caller. We may be able to return const-ref typed value or try std::move to avoid the copy.", + "pure_function": "This issue type indicates pure functions. For instance, below functions would be marked as pure:", + "quandary_taint_error": "Generic taint error when nothing else fits.", + "regex_op_on_ui_thread": "A potentially costly operation on a regular expression occurs on the UI thread.", + "resource_leak": "Infer reports resource leaks in C, Objective-C and Java. In general, resources are entities such as files, sockets, connections, etc, that need to be closed after being used.", + "resource-leak-in-c": "This is an example of a resource leak in C code:", + "resource-leak-in-java": "For the remaining of this section, we will consider examples of resource leaks in Java code.", + "basics-and-standard-idiom": "Some objects in Java, the resources, are supposed to be closed when you stop using them, and failure to close is a resource leak. Resources include input streams, output streams, readers, writers, sockets, http connections, cursors, and json parsers.", + "nested_allocations": "When a resource allocation is included as an argument to a constructor, if the constructor fails it can leave an unreachable resource that no one can close.", + "allocation-of-jsonparser-and-cursor-resources": "Some resources are created inside libraries instead of by \"new\".", + "escaping-resources-and-exceptions": "Sometimes you want to return a resource to the outside, in which case you should not close it, but you still need to be careful of exceptions in case control skips past the return leaving no one to close. Here is a simple example of a positive use of escaping resources.", + "java-7s-try-with-resources": "(For use with Java 7 only)", + "retain_cycle": "A retain cycle is a situation when object A retains object B, and object B retains object A at the same time. Here is an example:", + "retain_cycle_no_weak_info": "A retain cycle is a situation when object A retains object B, and object B retains object A at the same time. Here is an example:", + "scope_leakage": "This issue type indicates that a class with scope annotation A stores a field with whose (dynamic) type (or one of its super types) is annotated with scope B such that a scope nesting restriction is violated. By \"stores\", we mean either directly or transitively.", + "sensitive_data_flow": "A flow of sensitive data was detected from a source.", + "shell_injection": "Environment variable or file data flowing to shell.", + "shell_injection_risk": "Code injection if the caller of the endpoint doesn't sanitize on its end.", + "sql_injection": "Untrusted and unescaped data flows to SQL.", + "sql_injection_risk": "Untrusted and unescaped data flows to SQL.", + "stack_variable_address_escape": "Reported when an address pointing into the stack of the current function will escape to its calling context. Such addresses will become invalid by the time the function actually returns so are potentially dangerous.", + "starvation": "This error is reported in Java, and specifically on Android. These reports are triggered when a method that runs on the UI thread may block, thus potentially leading to an Application Not Responding error.", + "static_initialization_order_fiasco": "This error is reported in C++. It fires when the initialization of a static variable A, accesses a static variable B from another translation unit (usually another .cpp file). There are no guarantees whether B has been already initialized or not at that point.", + "strict_mode_violation": "Android has a feature called strict mode, which if enabled, will flag the occasions where the main thread makes a call that results in disk I/O, waiting on a network socket, etc. The analysis catching starvation errors and deadlocks (the --starvation analysis) has the ability to statically detect such violations.", + "strong_self_not_checked": "This checks reports a potential issue when a block captures weakSelf (a weak pointer to self), then one assigns this pointer to a local variable strongSelf inside the block and uses this variable without checking first whether it is nil. The problem here is that the weak pointer could be nil at the time when the block is executed. So, the correct usage is to first check whether strongSelf is a valid pointer, and then use it.", + "taint_error": "A taint flow was detected from a source to a sink", + "thread_safety_violation": "This warning indicates a potential data race in Java. The analyser is called RacerD and this section gives brief but a mostly complete description of its features. See the RacerD page for more in-depth information and examples.", + "thread-safety-what-is-a-data-race": "Here a data race is a pair of accesses to the same member field such that:", + "thread-safety-potential-fixes": "Synchronizing the accesses (using the synchronized keyword, thread-exclusion such as atomic objects, volatile etc). Making an offending method private -- this will exclude it from being checked at the top level, though it will be checked if called by a public method which may itself, e.g., hold a lock when calling it. Putting the two accesses on the same thread, e.g., by using @MainThread or @ThreadConfined.", + "thread-safety-conditions-checked-before-reporting": "The class and method are not marked @ThreadSafe(enableChecks = false), and,", + "thread-safety-thread-annotations-recognized-by-racerd": "These class and method annotations imply the method is on the main thread: @MainThread, @UiThread", + "thread-safety-other-annotations-and-what-they-do": "These annotations can be found at com.facebook.infer.annotation.*.", + "topl_error": "A violation of a Topl property (user-specified). There is an execution path in the code that drives a Topl property from a start state to an error state.", + "topl_error_latent": "A latent TOPL_ERROR. See the documentation on Pulse latent issues.", + "untrusted_buffer_access": "Untrusted data of any kind flowing to buffer.", + "untrusted_deserialization": "User-controlled deserialization.", + "untrusted_deserialization_risk": "User-controlled deserialization", + "untrusted_environment_change_risk": "User-controlled environment mutation.", + "untrusted_file": "User-controlled file creation; may be vulnerable to path traversal and more.", + "untrusted_file_risk": "User-controlled file creation; may be vulnerable to path traversal and more.", + "untrusted_heap_allocation": "Untrusted data of any kind flowing to heap allocation. this can cause crashes or DOS.", + "untrusted_intent_creation": "Creating an Intent from user-controlled data.", + "untrusted_url_risk": "Untrusted flag, environment variable, or file data flowing to URL.", + "untrusted_variable_length_array": "Untrusted data of any kind flowing to stack buffer allocation. Trying to allocate a stack buffer that's too large will cause a stack overflow.", + "user_controlled_sql_risk": "Untrusted data flows to SQL (no injection risk).", + "use_after_delete": "An address that was invalidated by a call to delete in C++ is dereferenced.", + "use_after_delete_latent": "A latent USE_AFTER_DELETE. See the documentation on Pulse latent issues.", + "use_after_free": "An address that was invalidated by a call to free in C is dereferenced.", + "use_after_free_latent": "A latent USE_AFTER_FREE. See the documentation on Pulse latent issues.", + "use_after_lifetime": "The lifetime of an object has ended but that object is being accessed. For example, the address of a variable holding a C++ object is accessed after the variable has gone out of scope:", + "use_after_lifetime_latent": "A latent USE_AFTER_LIFETIME. See the documentation on Pulse latent issues.", + "vector_invalidation": "An address pointing into a C++ std::vector might have become invalid. This can happen when an address is taken into a vector, then the vector is mutated in a way that might invalidate the address, for example by adding elements to the vector, which might trigger a re-allocation of the entire vector contents (thereby invalidating the pointers into the previous location of the contents).", + "vector_invalidation_latent": "A latent VECTOR_INVALIDATION. See the documentation on Pulse latent issues.", + "weak_self_in_no_escape_block": "This check reports when weakSelf (a weak pointer to self) is used in a block, and this block is passed to a \"no escaping\" method. This means that the block passed to that method won't be leaving the current scope, this is marked with the annotation NS_NOESCAPE." +} \ No newline at end of file diff --git a/analyzer/codechecker_analyzer/analyzers/infer/result_handler.py b/analyzer/codechecker_analyzer/analyzers/infer/result_handler.py new file mode 100644 index 0000000000..d0fd59877c --- /dev/null +++ b/analyzer/codechecker_analyzer/analyzers/infer/result_handler.py @@ -0,0 +1,77 @@ +# ------------------------------------------------------------------------- +# +# Part of the CodeChecker project, under the Apache License v2.0 with +# LLVM Exceptions. See LICENSE for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ------------------------------------------------------------------------- +""" +Result handler for Infer. +""" +from typing import Optional +from pathlib import Path +import shutil + +from codechecker_report_converter.report.parser.base import AnalyzerInfo +from codechecker_report_converter.analyzers.infer.analyzer_result import \ + AnalyzerResult +from codechecker_report_converter.report import report_file +from codechecker_report_converter.report.hash import get_report_hash, HashType + +from codechecker_common.logger import get_logger +from codechecker_common.skiplist_handler import SkipListHandlers +from codechecker_common.review_status_handler import ReviewStatusHandler + +from ..result_handler_base import ResultHandler + +LOG = get_logger('analyzer.infer') + + +class InferResultHandler(ResultHandler): + """ + Create analyzer result file for Infer output. + """ + + def __init__(self, *args, **kwargs): + self.analyzer_info = AnalyzerInfo(name=AnalyzerResult.TOOL_NAME) + self.infer_analyzer_result = AnalyzerResult() + + super().__init__(*args, **kwargs) + + def postprocess_result( + self, + skip_handlers: Optional[SkipListHandlers], + rs_handler: Optional[ReviewStatusHandler] + ): + """ + Generate analyzer result output file which can be parsed and stored + into the database. + """ + LOG.debug_analyzer(self.analyzer_stdout) + + infer_out_folder = Path(self.workspace, "infer") + infer_dest_file_name = Path(infer_out_folder, + self.buildaction_hash, "report.json") + + reports = self.infer_analyzer_result.get_reports(infer_dest_file_name) + + hash_type = HashType.PATH_SENSITIVE + if self.report_hash_type == 'context-free-v2': + hash_type = HashType.CONTEXT_FREE + elif self.report_hash_type == 'diagnostic-message': + hash_type = HashType.DIAGNOSTIC_MESSAGE + + for report in reports: + if not report.checker_name.startswith("infer-"): + nicer_name = report.checker_name.lower().replace("_", "-") + report.checker_name = "infer-" + nicer_name + report.report_hash = get_report_hash(report, hash_type) + + if rs_handler: + reports = [r for r in reports if not rs_handler.should_ignore(r)] + + report_file.create( + self.analyzer_result_file, reports, self.checker_labels, + self.analyzer_info) + + shutil.rmtree(Path(self.workspace, "infer", self.buildaction_hash)) diff --git a/analyzer/codechecker_analyzer/cmd/analyzers.py b/analyzer/codechecker_analyzer/cmd/analyzers.py index e235a08234..468ce0943f 100644 --- a/analyzer/codechecker_analyzer/cmd/analyzers.py +++ b/analyzer/codechecker_analyzer/cmd/analyzers.py @@ -145,6 +145,8 @@ def main(args): LOG.warning("'--dump-config cppcheck' is not supported.") elif args.dump_config == 'gcc': raise NotImplementedError('--dump-config') + elif args.dump_config == 'infer': + raise NotImplementedError('--dump-config') return diff --git a/analyzer/tests/functional/analyze/test_analyze.py b/analyzer/tests/functional/analyze/test_analyze.py index 88e46ad47c..ecabdaec4f 100644 --- a/analyzer/tests/functional/analyze/test_analyze.py +++ b/analyzer/tests/functional/analyze/test_analyze.py @@ -1198,7 +1198,7 @@ def test_disable_all_checkers(self): out, _ = process.communicate() # Checkers of all 3 analyzers are disabled. - self.assertEqual(out.count("No checkers enabled for"), 4) + self.assertEqual(out.count("No checkers enabled for"), 5) def test_analyzer_and_checker_config(self): """Test analyzer configuration through command line flags.""" diff --git a/analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py b/analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py index b50a6b2b81..97a202eef7 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py +++ b/analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py @@ -224,7 +224,9 @@ def check_one_file(self, path, mode): "clang-tidy:", "clangsa:", "cppcheck:", - "gcc:"] + "gcc:", + "infer:", + "Found 1 source file to analyze in"] for line in output: # replace timestamps line = re.sub(r'\[\w+ \d{4}-\d{2}-\d{2} \d{2}:\d{2}\]', diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/Makefile b/analyzer/tests/functional/analyze_and_parse/test_files/Makefile index 5a6d184ba1..3588216c4d 100644 --- a/analyzer/tests/functional/analyze_and_parse/test_files/Makefile +++ b/analyzer/tests/functional/analyze_and_parse/test_files/Makefile @@ -53,3 +53,5 @@ cppcheck_undef_include: $(CXX) -w cppcheck_include.cpp -I./includes/ -U HAVE_NULL_DEREFERENCE -o /dev/null gcc_simple: $(CXX) -w gcc_simple.cpp -o /dev/null -c +infer_simple: + $(CXX) -w infer_simple.cpp -o /dev/null -c \ No newline at end of file diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/infer_simple.cpp b/analyzer/tests/functional/analyze_and_parse/test_files/infer_simple.cpp new file mode 100644 index 0000000000..4286748488 --- /dev/null +++ b/analyzer/tests/functional/analyze_and_parse/test_files/infer_simple.cpp @@ -0,0 +1,6 @@ +int main() { + int a = 123; + int b = a + 456; + + return 0; +} \ No newline at end of file diff --git a/analyzer/tests/functional/analyze_and_parse/test_files/infer_simple.output b/analyzer/tests/functional/analyze_and_parse/test_files/infer_simple.output new file mode 100644 index 0000000000..8475611d25 --- /dev/null +++ b/analyzer/tests/functional/analyze_and_parse/test_files/infer_simple.output @@ -0,0 +1,57 @@ +NORMAL#CodeChecker log --output $LOGFILE$ --build "make infer_simple" --quiet +NORMAL#CodeChecker analyze $LOGFILE$ --output $OUTPUT$ --analyzers infer --enable=infer-dead-store +NORMAL#CodeChecker parse $OUTPUT$ +CHECK#CodeChecker check --build "make infer_simple" --output $OUTPUT$ --quiet --analyzers infer --enable=infer-dead-store +----------------------------------------------- +[] - Starting build... +[] - Using CodeChecker ld-logger. +[] - Build finished successfully. +[] - Starting static analysis ... +[] - [1/1] infer analyzed infer_simple.cpp successfully. +[] - ----==== Summary ====---- +[] - Successfully analyzed +[] - infer: 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] infer_simple.cpp:3:5: The value written to &b (type int) is never used. [infer-dead-store] + int b = a + 456; + ^ + +Found 1 defect(s) in infer_simple.cpp + + +----==== Severity Statistics ====---- +---------------------------- +Severity | Number of reports +---------------------------- +HIGH | 1 +---------------------------- +----=================---- + +----==== Checker Statistics ====---- +----------------------------------------------- +Checker name | Severity | Number of reports +----------------------------------------------- +infer-dead-store | HIGH | 1 +----------------------------------------------- +----=================---- + +----==== File Statistics ====---- +------------------------------------ +File name | Number of reports +------------------------------------ +infer_simple.cpp | 1 +------------------------------------ +----=================---- + +----======== Summary ========---- +--------------------------------------------- +Number of processed analyzer result files | 1 +Number of analyzer reports | 1 +--------------------------------------------- +----=================---- diff --git a/config/labels/analyzers/infer.json b/config/labels/analyzers/infer.json new file mode 100644 index 0000000000..70db334d4e --- /dev/null +++ b/config/labels/analyzers/infer.json @@ -0,0 +1,1230 @@ +{ + "analyzer": "infer", + "labels": { + "infer-arbitrary-code-execution-under-lock": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#arbitrary_code_execution_under_lock", + "profile:unknown", + "severity:HIGH" + ], + "infer-array-out-of-bounds-l1": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-array-out-of-bounds-l2": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-array-out-of-bounds-l3": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-abduction-case-not-implemented": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-array-of-pointsto": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-assert-failure": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-arg": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_arg", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-arg-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_arg_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-generator": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_generator", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-generator-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_generator_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-key": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_key", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-key-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_key_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-map": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_map", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-map-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_map_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-record": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_record", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-record-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_record_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-return": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_return", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-return-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_return_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-biabduction-analysis-stops": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-biabduction-memory-leak": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#biabduction_memory_leak", + "profile:unknown", + "severity:HIGH" + ], + "infer-biabduction-retain-cycle": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#biabduction_retain_cycle", + "profile:unknown", + "severity:HIGH" + ], + "infer-block-parameter-not-null-checked": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#block_parameter_not_null_checked", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-buffer-overrun-l1": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#buffer_overrun_l1", + "profile:unknown", + "severity:HIGH" + ], + "infer-buffer-overrun-l2": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#buffer_overrun_l2", + "profile:unknown", + "severity:HIGH" + ], + "infer-buffer-overrun-l3": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#buffer_overrun_l3", + "profile:unknown", + "severity:HIGH" + ], + "infer-buffer-overrun-l4": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#buffer_overrun_l4", + "profile:unknown", + "severity:HIGH" + ], + "infer-buffer-overrun-l5": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#buffer_overrun_l5", + "profile:unknown", + "severity:HIGH" + ], + "infer-buffer-overrun-s2": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#buffer_overrun_s2", + "profile:unknown", + "severity:HIGH" + ], + "infer-buffer-overrun-u5": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#buffer_overrun_u5", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-footprint": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-captured-strong-self": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#captured_strong_self", + "profile:unknown", + "severity:HIGH" + ], + "infer-checkers-allocates-memory": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#checkers_allocates_memory", + "profile:unknown", + "severity:HIGH" + ], + "infer-checkers-annotation-reachability-error": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#checkers_annotation_reachability_error", + "profile:unknown", + "severity:HIGH" + ], + "infer-checkers-calls-expensive-method": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#checkers_calls_expensive_method", + "profile:unknown", + "severity:HIGH" + ], + "infer-checkers-expensive-overrides-unannotated": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#checkers_expensive_overrides_unannotated", + "profile:unknown", + "severity:HIGH" + ], + "infer-checkers-fragment-retains-view": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#checkers_fragment_retains_view", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-checkers-printf-args": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#checkers_printf_args", + "profile:unknown", + "severity:HIGH" + ], + "infer-class-cast-exception": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-condition-always-false": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-condition-always-true": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-config-impact": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#config_impact", + "profile:unknown", + "severity:STYLE" + ], + "infer-config-impact-strict": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#config_impact_strict", + "profile:unknown", + "severity:STYLE" + ], + "infer-config-usage": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#config_usage", + "profile:unknown", + "severity:LOW" + ], + "infer-constant-address-dereference": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#constant_address_dereference", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-constant-address-dereference-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#constant_address_dereference_latent", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-create-intent-from-uri": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#create_intent_from_uri", + "profile:unknown", + "severity:HIGH" + ], + "infer-cross-site-scripting": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#cross_site_scripting", + "profile:unknown", + "severity:HIGH" + ], + "infer-cxx-ref-captured-in-block": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#cxx_ref_captured_in_block", + "profile:unknown", + "severity:HIGH" + ], + "infer-cannot-star": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-dangling-pointer-dereference": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#dangling_pointer_dereference", + "profile:unknown", + "severity:HIGH" + ], + "infer-dangling-pointer-dereference-maybe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-datalog-fact": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#datalog_fact", + "profile:unknown", + "severity:LOW" + ], + "infer-data-flow-to-sink": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#data_flow_to_sink", + "profile:unknown", + "severity:STYLE" + ], + "infer-deadlock": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#deadlock", + "profile:unknown", + "severity:HIGH" + ], + "infer-dead-store": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#dead_store", + "profile:unknown", + "severity:HIGH" + ], + "infer-divide-by-zero": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#divide_by_zero", + "profile:unknown", + "severity:HIGH" + ], + "infer-do-not-report": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-empty-vector-access": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#empty_vector_access", + "profile:unknown", + "severity:HIGH" + ], + "infer-execution-time-complexity-increase": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#execution_time_complexity_increase", + "profile:unknown", + "severity:HIGH" + ], + "infer-execution-time-complexity-increase-ui-thread": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#execution_time_complexity_increase_ui_thread", + "profile:unknown", + "severity:HIGH" + ], + "infer-execution-time-unreachable-at-exit": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#execution_time_unreachable_at_exit", + "profile:unknown", + "severity:HIGH" + ], + "infer-expensive-execution-time": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#expensive_execution_time", + "profile:unknown", + "severity:HIGH" + ], + "infer-expensive-loop-invariant-call": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#expensive_loop_invariant_call", + "profile:unknown", + "severity:HIGH" + ], + "infer-exposed-insecure-intent-handling": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#exposed_insecure_intent_handling", + "profile:unknown", + "severity:HIGH" + ], + "infer-failure-exe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:LOW" + ], + "infer-guardedby-violation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#guardedby_violation", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-impure-function": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#impure_function", + "profile:unknown", + "severity:HIGH" + ], + "infer-inefficient-keyset-iterator": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#inefficient_keyset_iterator", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-inferbo-alloc-is-big": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#inferbo_alloc_is_big", + "profile:unknown", + "severity:HIGH" + ], + "infer-inferbo-alloc-is-negative": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#inferbo_alloc_is_negative", + "profile:unknown", + "severity:HIGH" + ], + "infer-inferbo-alloc-is-zero": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#inferbo_alloc_is_zero", + "profile:unknown", + "severity:HIGH" + ], + "infer-inferbo-alloc-may-be-big": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#inferbo_alloc_may_be_big", + "profile:unknown", + "severity:HIGH" + ], + "infer-inferbo-alloc-may-be-negative": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#inferbo_alloc_may_be_negative", + "profile:unknown", + "severity:HIGH" + ], + "infer-infinite-execution-time": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#infinite_execution_time", + "profile:unknown", + "severity:HIGH" + ], + "infer-inherently-dangerous-function": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-insecure-intent-handling": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#insecure_intent_handling", + "profile:unknown", + "severity:HIGH" + ], + "infer-integer-overflow-l1": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#integer_overflow_l1", + "profile:unknown", + "severity:HIGH" + ], + "infer-integer-overflow-l2": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#integer_overflow_l2", + "profile:unknown", + "severity:HIGH" + ], + "infer-integer-overflow-l5": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#integer_overflow_l5", + "profile:unknown", + "severity:HIGH" + ], + "infer-integer-overflow-u5": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#integer_overflow_u5", + "profile:unknown", + "severity:HIGH" + ], + "infer-interface-not-thread-safe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#interface_not_thread_safe", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-invalid-sil": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#invalid_sil", + "profile:unknown", + "severity:HIGH" + ], + "infer-invariant-call": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#invariant_call", + "profile:unknown", + "severity:HIGH" + ], + "infer-ipc-on-ui-thread": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#ipc_on_ui_thread", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-internal-error": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-javascript-injection": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#javascript_injection", + "profile:unknown", + "severity:HIGH" + ], + "infer-lab-resource-leak": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#lab_resource_leak", + "profile:unknown", + "severity:HIGH" + ], + "infer-lockless-violation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#lockless_violation", + "profile:unknown", + "severity:HIGH" + ], + "infer-lock-consistency-violation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#lock_consistency_violation", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-logging-private-data": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#logging_private_data", + "profile:unknown", + "severity:HIGH" + ], + "infer-leak-after-array-abstraction": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-leak-in-footprint": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-leak-unknown-origin": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-memory-leak-c": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#memory_leak_c", + "profile:unknown", + "severity:HIGH" + ], + "infer-memory-leak-cpp": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#memory_leak_cpp", + "profile:unknown", + "severity:HIGH" + ], + "infer-missing-required-prop": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#missing_required_prop", + "profile:unknown", + "severity:HIGH" + ], + "infer-mixed-self-weakself": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#mixed_self_weakself", + "profile:unknown", + "severity:HIGH" + ], + "infer-modifies-immutable": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#modifies_immutable", + "profile:unknown", + "severity:HIGH" + ], + "infer-multiple-weakself": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#multiple_weakself", + "profile:unknown", + "severity:HIGH" + ], + "infer-mutual-recursion-cycle": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#mutual_recursion_cycle", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-missing-fld": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-nil-block-call": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nil_block_call", + "profile:unknown", + "severity:HIGH" + ], + "infer-nil-block-call-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nil_block_call_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-nil-insertion-into-collection": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nil_insertion_into_collection", + "profile:unknown", + "severity:HIGH" + ], + "infer-nil-insertion-into-collection-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nil_insertion_into_collection_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-nil-messaging-to-non-pod": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nil_messaging_to_non_pod", + "profile:unknown", + "severity:HIGH" + ], + "infer-nil-messaging-to-non-pod-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nil_messaging_to_non_pod_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-matching-branch-in-try": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_matching_branch_in_try", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-matching-branch-in-try-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_matching_branch_in_try_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-matching-case-clause": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_matching_case_clause", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-matching-case-clause-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_matching_case_clause_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-matching-else-clause": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_matching_else_clause", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-matching-else-clause-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_matching_else_clause_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-matching-function-clause": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_matching_function_clause", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-matching-function-clause-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_matching_function_clause_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-match-of-rhs": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_match_of_rhs", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-match-of-rhs-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_match_of_rhs_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-true-branch-in-if": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_true_branch_in_if", + "profile:unknown", + "severity:HIGH" + ], + "infer-no-true-branch-in-if-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#no_true_branch_in_if_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-nullptr-dereference": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nullptr_dereference", + "profile:unknown", + "severity:HIGH" + ], + "infer-nullptr-dereference-in-nullsafe-class": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nullptr_dereference_in_nullsafe_class", + "profile:unknown", + "severity:HIGH" + ], + "infer-nullptr-dereference-in-nullsafe-class-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nullptr_dereference_in_nullsafe_class_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-nullptr-dereference-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#nullptr_dereference_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-null-argument": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#null_argument", + "profile:unknown", + "severity:HIGH" + ], + "infer-null-argument-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#null_argument_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-null-dereference": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#null_dereference", + "profile:unknown", + "severity:HIGH" + ], + "infer-optional-empty-access": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#optional_empty_access", + "profile:unknown", + "severity:HIGH" + ], + "infer-optional-empty-access-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#optional_empty_access_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-precondition-not-found": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-precondition-not-met": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-premature-nil-termination-argument": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#premature_nil_termination_argument", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-pulse-cannot-instantiate-abstract-class": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_cannot_instantiate_abstract_class", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-const-refable": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_const_refable", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-dict-missing-key": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_dict_missing_key", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-dynamic-type-mismatch": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_dynamic_type_mismatch", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-readonly-shared-ptr-param": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_readonly_shared_ptr_param", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-reference-stability": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_reference_stability", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-resource-leak": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_resource_leak", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-transitive-access": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_transitive_access", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unawaited-awaitable": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unawaited_awaitable", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-uninitialized-const": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_uninitialized_const", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-uninitialized-value": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_uninitialized_value", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-assignment": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_assignment", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-assignment-const": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_assignment_const", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-assignment-movable": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_assignment_movable", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-intermediate": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_intermediate", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-intermediate-const": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_intermediate_const", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-movable": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_movable", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-optional": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_optional", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-optional-const": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_optional_const", + "profile:unknown", + "severity:HIGH" + ], + "infer-pulse-unnecessary-copy-return": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pulse_unnecessary_copy_return", + "profile:unknown", + "severity:HIGH" + ], + "infer-pure-function": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pure_function", + "profile:unknown", + "severity:HIGH" + ], + "infer-quandary-taint-error": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#quandary_taint_error", + "profile:unknown", + "severity:HIGH" + ], + "infer-regex-op-on-ui-thread": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#regex_op_on_ui_thread", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-resource-leak": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#resource_leak", + "profile:unknown", + "severity:HIGH" + ], + "infer-retain-cycle": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#retain_cycle", + "profile:unknown", + "severity:HIGH" + ], + "infer-retain-cycle-no-weak-info": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#retain_cycle_no_weak_info", + "profile:unknown", + "severity:HIGH" + ], + "infer-scope-leakage": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#scope_leakage", + "profile:unknown", + "severity:HIGH" + ], + "infer-sensitive-data-flow": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#sensitive_data_flow", + "profile:unknown", + "severity:STYLE" + ], + "infer-shell-injection": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#shell_injection", + "profile:unknown", + "severity:HIGH" + ], + "infer-shell-injection-risk": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#shell_injection_risk", + "profile:unknown", + "severity:HIGH" + ], + "infer-skip-function": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:LOW" + ], + "infer-sql-injection": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#sql_injection", + "profile:unknown", + "severity:HIGH" + ], + "infer-sql-injection-risk": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#sql_injection_risk", + "profile:unknown", + "severity:HIGH" + ], + "infer-stack-variable-address-escape": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#stack_variable_address_escape", + "profile:unknown", + "severity:HIGH" + ], + "infer-starvation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#starvation", + "profile:unknown", + "severity:HIGH" + ], + "infer-static-initialization-order-fiasco": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#static_initialization_order_fiasco", + "profile:unknown", + "severity:HIGH" + ], + "infer-strict-mode-violation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#strict_mode_violation", + "profile:unknown", + "severity:HIGH" + ], + "infer-strong-self-not-checked": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#strong_self_not_checked", + "profile:unknown", + "severity:HIGH" + ], + "infer-symexec-memory-error": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-taint-error": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#taint_error", + "profile:unknown", + "severity:HIGH" + ], + "infer-thread-safety-violation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#thread_safety_violation", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-topl-error": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#topl_error", + "profile:unknown", + "severity:HIGH" + ], + "infer-topl-error-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#topl_error_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-unreachable-code": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-buffer-access": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_buffer_access", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-deserialization": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_deserialization", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-deserialization-risk": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_deserialization_risk", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-environment-change-risk": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_environment_change_risk", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-file": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_file", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-file-risk": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_file_risk", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-heap-allocation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_heap_allocation", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-intent-creation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_intent_creation", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-url-risk": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_url_risk", + "profile:unknown", + "severity:HIGH" + ], + "infer-untrusted-variable-length-array": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#untrusted_variable_length_array", + "profile:unknown", + "severity:HIGH" + ], + "infer-user-controlled-sql-risk": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#user_controlled_sql_risk", + "profile:unknown", + "severity:HIGH" + ], + "infer-use-after-delete": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#use_after_delete", + "profile:unknown", + "severity:HIGH" + ], + "infer-use-after-delete-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#use_after_delete_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-use-after-free": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#use_after_free", + "profile:unknown", + "severity:HIGH" + ], + "infer-use-after-free-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#use_after_free_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-use-after-lifetime": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#use_after_lifetime", + "profile:unknown", + "severity:HIGH" + ], + "infer-use-after-lifetime-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#use_after_lifetime_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-vector-invalidation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#vector_invalidation", + "profile:unknown", + "severity:HIGH" + ], + "infer-vector-invalidation-latent": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#vector_invalidation_latent", + "profile:unknown", + "severity:HIGH" + ], + "infer-weak-self-in-no-escape-block": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#weak_self_in_no_escape_block", + "profile:unknown", + "severity:HIGH" + ], + "infer-wrong-argument-number": [ + "doc_url:https://fbinfer.com/docs/all-issue-types", + "profile:unknown", + "severity:HIGH" + ], + "infer-assign-pointer-MEDIUM": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#assign_pointer_MEDIUM", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-autoreleasepool-size-complexity-increase": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#autoreleasepool_size_complexity_increase", + "profile:unknown", + "severity:HIGH" + ], + "infer-autoreleasepool-size-complexity-increase-ui-thread": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#autoreleasepool_size_complexity_increase_ui_thread", + "profile:unknown", + "severity:HIGH" + ], + "infer-autoreleasepool-size-unreachable-at-exit": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#autoreleasepool_size_unreachable_at_exit", + "profile:unknown", + "severity:HIGH" + ], + "infer-bad-pointer-comparison": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#bad_pointer_comparison", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-checkers-annotation-reachability-HIGH": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#checkers_annotation_reachability_HIGH", + "profile:unknown", + "severity:HIGH" + ], + "infer-checkers-immutable-cast": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#checkers_immutable_cast", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-component-with-multiple-factory-methods": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#component_with_multiple_factory_methods", + "profile:unknown", + "severity:LOW" + ], + "infer-config-checks-between-markers": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#config_checks_between_markers", + "profile:unknown", + "severity:LOW" + ], + "infer-cxx-reference-captured-in-objc-block": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#cxx_reference_captured_in_objc_block", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-direct-atomic-property-access": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#direct_atomic_property_access", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-discouraged-weak-property-custom-setter": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#discouraged_weak_property_custom_setter", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-dotnet-resource-leak": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#dotnet_resource_leak", + "profile:unknown", + "severity:HIGH" + ], + "infer-eradicate-annotation-graph": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_annotation_graph", + "profile:unknown", + "severity:STYLE" + ], + "infer-eradicate-bad-nested-class-annotation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_bad_nested_class_annotation", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-eradicate-condition-redundant": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_condition_redundant", + "profile:unknown", + "severity:LOW" + ], + "infer-eradicate-field-not-initialized": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_field_not_initialized", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-eradicate-field-not-nullable": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_field_not_nullable", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-eradicate-field-over-annotated": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_field_over_annotated", + "profile:unknown", + "severity:LOW" + ], + "infer-eradicate-inconsistent-subclass-parameter-annotation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_inconsistent_subclass_parameter_annotation", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-eradicate-inconsistent-subclass-return-annotation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_inconsistent_subclass_return_annotation", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-eradicate-meta-class-can-be-nullsafe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_meta_class_can_be_nullsafe", + "profile:unknown", + "severity:LOW" + ], + "infer-eradicate-meta-class-is-nullsafe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_meta_class_is_nullsafe", + "profile:unknown", + "severity:STYLE" + ], + "infer-eradicate-meta-class-needs-improvement": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_meta_class_needs_improvement", + "profile:unknown", + "severity:STYLE" + ], + "infer-eradicate-nullable-dereference": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_nullable_dereference", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-eradicate-parameter-not-nullable": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_parameter_not_nullable", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-eradicate-redundant-nested-class-annotation": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_redundant_nested_class_annotation", + "profile:unknown", + "severity:LOW" + ], + "infer-eradicate-return-not-nullable": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_return_not_nullable", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-eradicate-return-over-annotated": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_return_over_annotated", + "profile:unknown", + "severity:LOW" + ], + "infer-eradicate-unchecked-usage-in-nullsafe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_unchecked_usage_in_nullsafe", + "profile:unknown", + "severity:UNSPECIFIED" + ], + "infer-eradicate-unvetted-third-party-in-nullsafe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#eradicate_unvetted_third_party_in_nullsafe", + "profile:unknown", + "severity:UNSPECIFIED" + ], + "infer-expensive-autoreleasepool-size": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#expensive_autoreleasepool_size", + "profile:unknown", + "severity:HIGH" + ], + "infer-global-variable-initialized-with-function-or-method-call": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#global_variable_initialized_with_function_or_method_call", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-guardedby-violation-nullsafe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#guardedby_violation_nullsafe", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-infinite-autoreleasepool-size": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#infinite_autoreleasepool_size", + "profile:unknown", + "severity:HIGH" + ], + "infer-ivar-not-null-checked": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#ivar_not_null_checked", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-memory-leak": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#memory_leak", + "profile:unknown", + "severity:HIGH" + ], + "infer-mutable-local-variable-in-component-file": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#mutable_local_variable_in_component_file", + "profile:unknown", + "severity:LOW" + ], + "infer-parameter-not-null-checked": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#parameter_not_null_checked", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-pointer-to-const-objc-class": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#pointer_to_const_objc_class", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-quandary-taint-HIGH": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#quandary_taint_HIGH", + "profile:unknown", + "severity:HIGH" + ], + "infer-strong-delegate-MEDIUM": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#strong_delegate_MEDIUM", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-thread-safety-violation-nullsafe": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#thread_safety_violation_nullsafe", + "profile:unknown", + "severity:MEDIUM" + ], + "infer-topl-HIGH": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#topl_HIGH", + "profile:unknown", + "severity:HIGH" + ], + "infer-uninitialized-value": [ + "doc_url:https://fbinfer.com/docs/all-issue-types#uninitialized_value", + "profile:unknown", + "severity:HIGH" + ], + "infer-internal-HIGH": [ + "doc_url:https://fbinfer.com/docs/all-issue-types##", + "profile:unknown", + "severity:HIGH" + ], + "infer-symexec-memory-HIGH": [ + "doc_url:https://fbinfer.com/docs/all-issue-types##", + "profile:unknown", + "severity:HIGH" + ] + } +} \ No newline at end of file diff --git a/config/package_layout.json b/config/package_layout.json index 49579fe89b..d38cc59509 100644 --- a/config/package_layout.json +++ b/config/package_layout.json @@ -4,7 +4,8 @@ "clangsa": "clang", "clang-tidy": "clang-tidy", "cppcheck": "cppcheck", - "gcc": "g++" + "gcc": "g++", + "infer": "infer" }, "clang-apply-replacements": "clang-apply-replacements" }, diff --git a/docs/README.md b/docs/README.md index 69ebf2f77a..d3ef0fe516 100644 --- a/docs/README.md +++ b/docs/README.md @@ -36,7 +36,7 @@ macOS (OS X) development environment. # Main features ## Command line C/C++ Analysis - * Executes [_Clang-Tidy_](http://clang.llvm.org/extra/clang-tidy/), [_Clang Static Analyzer_](http://clang-analyzer.llvm.org/) with Cross-Translation Unit analysis, Statistical Analysis (when checkers are available), [_Cppcheck_](https://cppcheck.sourceforge.io/), and the [_GCC Static Analyzer_](https://gcc.gnu.org/wiki/StaticAnalyzer). + * Executes [_Clang-Tidy_](http://clang.llvm.org/extra/clang-tidy/), [_Clang Static Analyzer_](http://clang-analyzer.llvm.org/) with Cross-Translation Unit analysis, Statistical Analysis (when checkers are available), [_Cppcheck_](https://cppcheck.sourceforge.io/), [_GCC Static Analyzer_](https://gcc.gnu.org/wiki/StaticAnalyzer) and the [_Facebook Infer Analyzer_](https://fbinfer.com). * Creates the JSON compilation database by wiretapping any build process (e.g., `CodeChecker log -b "make"`). * Automatically analyzes GCC cross-compiled projects: detecting GCC or Clang compiler configuration and forming the corresponding clang analyzer invocations. * Incremental analysis: Only the changed files and its dependencies need to be reanalyzed. @@ -243,6 +243,7 @@ The following commands are used to bootstrap CodeChecker on Ubuntu 20.04 LTS: # come from package manager! # In case of Cppcheck, the minimal supported version is 1.80. # In case of gcc, the minimal supported version is 13.0.0. +# Infer: https://fbinfer.com/docs/getting-started sudo apt-get install clang clang-tidy cppcheck g++ build-essential curl gcc-multilib git python3-dev python3-venv python3-setuptools diff --git a/docs/analyzer/checker_and_analyzer_configuration.md b/docs/analyzer/checker_and_analyzer_configuration.md index 637d513660..5359edb2f3 100644 --- a/docs/analyzer/checker_and_analyzer_configuration.md +++ b/docs/analyzer/checker_and_analyzer_configuration.md @@ -300,3 +300,29 @@ CodeChecker check -l ./compile_commands.json \ -d gcc-double-free \ # disable gcc-double-free -o ./reports ``` + +# Configuring the FB-Infer Analyzer + +As of CodeChecker 6.23, Codechecker can now execute the Facebook Infer Analyzer. +The minimum version of Infer we support is 1.1.0. + +## Analyzer Configuration + +Currently, we don't support configuring the Facebook Infer analyzer through +CodeChecker. The _overwhelming_ majority of these configurations are only +recommended for developers -- but we will keep an eye out if this ever changes. + +## Limitations + +Currently only static analysis can be executed. Meaning that it analyzes each +file separately and not the whole project as one. + +## Example invocation + +``` shell +CodeChecker check -l ./compile_commands.json \ + --analyzers infer \ # Run Infer analyzer only + -e infer \ # enable all checkers starting with "infer" + -d infer-expensive-loop-invariant-call \ # disable infer-expensive-loop-invariant-call + -o ./reports +``` \ No newline at end of file diff --git a/docs/analyzer/user_guide.md b/docs/analyzer/user_guide.md index b66a96e193..e8bba6ad95 100644 --- a/docs/analyzer/user_guide.md +++ b/docs/analyzer/user_guide.md @@ -1208,6 +1208,7 @@ the [_Clang Static Analyzer_](http://clang-analyzer.llvm.org), [_Clang-Tidy_](http://clang.llvm.org/extra/clang-tidy), [_Cppcheck_](http://cppcheck.sourceforge.net/) and [_GCC Static Analyzer_](https://gcc.gnu.org/wiki/StaticAnalyzer). +[_Facebook Infer Analyzer_](https://fbinfer.com/) `--analyzers` can be used to specify which analyzer tool should be used (by default, all supported are used). The tools are completely independent, so either can be omitted if not present as they are provided by different diff --git a/docs/supported_code_analyzers.md b/docs/supported_code_analyzers.md index 3ce580e5c9..b828b6122b 100644 --- a/docs/supported_code_analyzers.md +++ b/docs/supported_code_analyzers.md @@ -5,6 +5,7 @@ CodeChecker can execute the following static analyzer tools: - [Clang Static Analyzer](https://clang-analyzer.llvm.org/) - [Cppcheck](https://cppcheck.sourceforge.io/) - [GCC Static Analyzer](https://gcc.gnu.org/wiki/StaticAnalyzer) +- [Facebook Infer Analyzer](https://fbinfer.com/) We have created a separate [converter tool](/tools/report-converter) which can be used to convert the output of different source code analyzer tools to a diff --git a/tools/report-converter/codechecker_report_converter/analyzers/infer/analyzer_result.py b/tools/report-converter/codechecker_report_converter/analyzers/infer/analyzer_result.py index f351d91f3b..d4af69c04a 100644 --- a/tools/report-converter/codechecker_report_converter/analyzers/infer/analyzer_result.py +++ b/tools/report-converter/codechecker_report_converter/analyzers/infer/analyzer_result.py @@ -78,6 +78,10 @@ def __get_abs_path(self, source_path): if os.path.exists(full_path): return full_path + abs_path_corrected = os.path.join('/', source_path) + if os.path.exists(abs_path_corrected): + return abs_path_corrected + LOG.warning("No source file found: %s", source_path) return None