| # The Clang Static Analyzer |
| |
| The Clang C/C++ compiler comes with a static analyzer which can be used to find |
| bugs using path sensitive analysis. Path sensitive analysis is |
| a technique that explores all the possible branches in code and |
| records the codepaths that might lead to bad or undefined behavior, |
| like an uninitialized reads, use after frees, pointer leaks, and so on. |
| |
| See the [official Clang static analyzer page](http://clang-analyzer.llvm.org/) |
| for more background information. |
| |
| We used to have a bot that continuously ran with the static analyzer, |
| but people used to not look at it much. |
| |
| The static analyzer can still be invoked with [clang-tidy](clang_tidy.md). |
| |
| ## Recommended checks |
| Clang's static analyzer comes with a wide variety of checkers. Some of the |
| checks aren't useful because they are intended for different languages, |
| platforms, or coding conventions than the ones used for Chromium development. |
| |
| Checkers we found useful were: |
| |
| -analyzer-checker=core |
| -analyzer-checker=cpp |
| -analyzer-checker=unix |
| -analyzer-checker=deadcode |
| |
| As of this writing, the checker suites we support are |
| [core](https://clang-analyzer.llvm.org/available_checks.html#core_checkers), |
| [cplusplus](https://clang-analyzer.llvm.org/available_checks.html#cplusplus_checkers), and |
| [deadcode](https://clang-analyzer.llvm.org/available_checks.html#deadcode_checkers). |
| |
| To easily run these checks against Chromium code via clang-tidy, follow |
| [these](clang_tidy.md#evaluating_running-clang_tidy-across-chromium) |
| instructions to pull down `tricium_clang_tidy.py` and then pass the following |
| argument when invoking the script (`-*` disables all checks and then the |
| remaining check name globs enable each category of checks): |
| ``` |
| --tidy_checks="-*,clang-analyzer-core*,clang-analyzer-cplusplus*,clang-analyzer-unix*,clang-analyzer-deadcode*" |
| ``` |
| A full list of Clang analyzer checks can be found in the |
| [Clang-Tidy Checks List](https://clang.llvm.org/extra/clang-tidy/checks/list.html). |
| |
| ## Addressing false positives |
| |
| Some of the errors you encounter will be false positives, which occurs when the |
| static analyzer naively follows codepaths which are practically impossible to |
| hit at runtime. Fortunately, we have a tool at our disposal for guiding the |
| analyzer away from impossible codepaths: assertion handlers like |
| DCHECK/CHECK/LOG(FATAL). The analyzer won't check the codepaths which we |
| assert are unreachable. |
| |
| An example would be that if the analyzer detected the function argument |
| `*my_ptr` might be null and dereferencing it would potentially segfault, you |
| would see the error `warning: Dereference of null pointer (loaded from variable |
| 'my_ptr')`. If you know for a fact that my_ptr will not be null in practice, |
| then you can place an assert at the top of the function: `DCHECK(my_ptr)`. The |
| analyzer will no longer generate the warning. |
| |
| Be mindful about only specifying assertions which are factually correct! Don't |
| DCHECK recklessly just to quiet down the analyzer. :) |
| |
| Other types of false positives and their suppressions: |
| * Unreachable code paths. To suppress, add the `ANALYZER_SKIP_THIS_PATH();` |
| directive to the relevant code block. |
| * Dead stores. To suppress, use `[[maybe_unused]]`. This also suppresses dead |
| store warnings on conventional builds without static analysis enabled! |
| |
| See the definitions of the `ANALYZER_*` macros in base/logging.h for more |
| detailed information about how the annotations are implemented. |
| |
| ## Logging bugs |
| |
| If you find any issues with the static analyzer, or find Chromium code behaving |
| badly with the analyzer, please check the `Infra>CodeAnalysis` CrBug component |
| to look for known issues, or file a bug if it is a new problem. |