# Compiler security tools
The LLVM release includes the following tools for performing static analysis on a program:
- Static analyzer - A tool that analyzes source code to find potential bugs in C and C+ programs.
- Postprocessor - A tool that creates a summary of the reports that are generated by performing static analysis while compiling a program.
## Static analyzer
The static analyzer is a source code analysis tool that is integrated into the LLVM compiler. It analyzes a program for potential bugs—including security threats, memory corruption, and garbage values—and generates a diagnostic report describing the potential bugs it detected.
The static analyzer has the following features:
- It supports more than 100 distinct *checkers* that are organized into the `alpha`, `core`, `cplusplus`, `debug`, and `security` categories
- Checkers can be selectively enabled or disabled from the command line
- Disabling a checker category disables all the checkers in that category
- Selected parts of the program code can be excluded from checking
### Analyze programs
To use the static analyzer on an entire program, invoke the LLVM compiler on the program using the `--compile-and-analyze` option
(see [Compiler security](https://docs.qualcomm.com/doc/80-N3040-23/topic/use-the-compilers.html#hccpp-compiler-options-compiler-security-sub)). For example:
hexagon-clang --compile-and-analyze
...
Copy to clipboard
- `--compile-and-analyze ` specifies the directory where the static analyzer report will be stored. (If the directory does not exist, the compiler automatically creates it.). The report is automatically generated in HTML format. The files are named `report*.html`.
- `` specifies the program source files.
We recommend statically analyzing an entire program at once (as opposed to selected source files) for the following reasons:
- The generated analysis report files are all stored in a single location.
- The command option can be passed from the build system, which helps perform the static analysis and compilation every time the program is
built.
- Because build systems are good at tracking files that have changed, and compiling only the minimal set of required files, the overall turnaround time for static analysis is relatively small, making it reasonable to run the static analyzer with every build.
Note
When using a build system, specifying the same directory name throughout the build generates all the HTML report files in the specified directory. The filenames generated for a report are based on hashing functions, so the report files are not overwritten.
### Analyze programs using default flags
To use the static analyzer on specific program source files, invoke the LLVM compiler on the files using the static analyzer options
(see [Compiler security](https://docs.qualcomm.com/doc/80-N3040-23/topic/use-the-compilers.html#hccpp-compiler-options-compiler-security-sub)). For example:
hexagon-clang --analyze -Xclang -analyzer-output -Xclang html -o
Copy to clipboard
Where:
- `--analyze` causes the compiler to generate a static analyzer report instead of a program object file.
- `-analyzer-output html` specifies that the report is generated in HTML format.
Note
`-Xclang` must be used (twice) to pass the `-analyzer-output` html option to the compiler. For details, see [Compilation](https://docs.qualcomm.com/doc/80-N3040-23/topic/use-the-compilers.html#hccpp-compiler-options-compilation-sub).
- `-o` specifies the directory where the report files will be stored. (If the directory does not exist, the compiler automatically creates it.). The files are named `report*.html`.
- `` specifies the program source files to be analyzed.
Example of a diagnostic report entry:
// @file: test.cpp
int main() {
int* p = new int();
return* p;
}
warning: Potential leak of memory pointed to by 'p'
Copy to clipboard
Each potential bug flagged in a report includes the path (control and data) required for locating the bug in the program.
Note
To convert static analyzer warnings to errors, use the `-analyzer-werror` option.
### Analyze programs with priority modes
In addition to the default `--compile-and-analyze` flag, the static analyzer also offers a list of specific directives for more targeted analysis.
- High Priority mode - This mode turns on the highest priority checkers that catch critical issues and have low false positive rates.
This mode can be enabled by the `--compile-and-analyze-high` flag.
- Medium Priority mode - This mode is slightly more inclusive compared to the high priority mode, but it still avoids some noisy checkers that are enabled by default.
This mode can be enabled by the `--compile-and-analyze-medium` flag.
- KW mode - This mode reduces issues that are typically caught by commercial static analysis tools. It is especially helpful if you want to catch those issues early in the development process.
Enable this mode with the `--compile-and-analyze-kw` flag.
### Manage checkers
The static analyzer supports more than 100 individual checkers that can analyze programs for various types of potential bugs. By default, only a subset of these checkers is enabled, to minimize both the compile time and the generation of false positives.
To enable additional checkers, invoke the static analyzer using the -analyzer-checker option (see [Compiler security](https://docs.qualcomm.com/doc/80-N3040-23/topic/use-the-compilers.html#hccpp-compiler-options-compiler-security-sub)). This option specifies the checker to be enabled (in the following example, `NewDelete`).
clang++ --compile-and-analyze -Xclang -analyzer-checker=cplusplus.NewDelete test.cpp
Copy to clipboard
To disable individual checkers, invoke the static analyzer using the `-analyzer-disable-checker` option (see [Compiler security](https://docs.qualcomm.com/doc/80-N3040-23/topic/use-the-compilers.html#hccpp-compiler-options-compiler-security-sub)). For example:
clang++ --compile-and-analyze -Xclang -analyzer-disable-checker= deadcode.deadstore test.cpp
Copy to clipboard
Note
-Xclang must be used to pass the `-analyzer-output`, `-analyzer-checker`, and `-analyzer-disable-checker` options to the compiler. For details, see [Compiler security](https://docs.qualcomm.com/doc/80-N3040-23/topic/use-the-compilers.html#hccpp-compiler-options-compiler-security-sub).
To list all the supported checkers, use the following command:
hexagon-clang -cc1 -analyzer-checker-help
Copy to clipboard
To list only the default checkers, use the -v option while running the analyzer on a test file ([Display](https://docs.qualcomm.com/doc/80-N3040-23/topic/use-the-compilers.html#hccpp-compiler-options-display-sub)). For example:
clang++ -v --compile-and-analyze --analyzer-perf test.cpp
Copy to clipboard
#### Packages
The individual checkers are organized into the following categories:
- `alpha`
- `core`
- `cplusplus` (only for analyzing C++ programs)
- `debug`
- `security`
- `unix`
- `optin`
Each category (or package) is defined to include a number of checkers. For example, the checker `NullDereference` is a `core` checker, while `NewDelete` is a `cplusplus` checker. Organizing checkers into packages (and sub-packages) makes it easier to enable/disable specific sets of checkers.
Example of using the static analyzer with all `alpha` checkers enabled:
hexagon-clang --compile-and-analyze -Xclang -analyzer-checker=alpha test.cpp
Copy to clipboard
### Lists
To enable or disable multiple individual checkers, multiple checker and package names can be specified as a single comma-separated list. For example:
hexagon-clang --compile-and-analyze -Xclang -analyzer-checker=alpha,core test.cpp
Copy to clipboard
### Cross-file analysis
A limitation of the clang static analyzer is its inability to analyze code that is called across file boundaries. This is due to the nature of the compiler, which compiles files individually. This feature enables the clang static analyzer to perform its analysis on code that is called across file boundaries.
The cross-translation unit (CTU) feature allows the analysis of called functions even if the definition of the function is external to the currently analyzed file. This feature allows detection of bugs in library functions stemming from incorrect usage. If an external function is invoked, this feature also allows for more precise analysis of the caller in general.
Enabling CTU analysis is a three-step process:
1. Generate the `compile_commands.json` file.
The makefile is read by the intercept-build script. This script is responsible for creating a compile\_commands.json file that contains a list of every build command that is run from this build system.
$share/scan-build-py/bin/intercept-build make
Copy to clipboard
2. Generate the AST database.
Generate the ASTs of every function in the build tree by issuing the following command:
$share/scan-build-py/bin/analyze-build --cdb -o
--ctu-collect-only --ctudir
Copy to clipboard
3. Run the cross-file analysis.
Kick off the static analyzer in the usual way (with the `--compile-and-analyze` flag) but with following added flags:
-Xclang -analyzer-checker=debug.ExprInspection -Xclang -analyzer-config -Xclang -ctu-dir=
Copy to clipboard
### Handle false positives
While checking a program for potential bugs, the static analyzer might report false positives, which are sections of code that the analyzer incorrectly flags as bugs.
To minimize false positives, the static analyzer, by default, enables a set of checkers that has been tested to identify a high percentage of actual program bugs (see [Manage checkers](https://docs.qualcomm.com/doc/80-N3040-23/topic/compiler-security-tools.html#hccpp-static-analyzer-manage-checkers-sub)). And if necessary, additional checkers can be individually enabled.
However, despite the overall accuracy of the checkers, several cases still exist where false positives can be generated. For instance, if you enable the checker used to analyze dead code, the static analyzer will flag as a false positive any code that has been conditionally enabled for debugging purposes.
To handle such cases, the static analyzer supports several features for handling false positives:
- Compile-time blacklist file
- Special comment
- Preprocessor symbol
- Function attribute
- Postprocess blacklist file
We do not recommend using comments or symbols to handle false positives because they make the code inaccessible to the analyzer. Instead, report any false positives so the existing checkers can be improved to eliminate them. For more information on false positives, go to:
[http://clang-analyzer.llvm.org/faq.html](http://clang-analyzer.llvm.org/faq.html)
#### Compile-time blacklist file
To silence warnings before they are reported by the analyzer, use the external file-based suppression mechanism. Enable this mechanism by
adding the compiler flag, `-analyzer-suppression-file `.
Suppression data in this text file must be entered line-by-line with the following format:
>
Copy to clipboard
The analyzer reads the contents of this file during the analysis and does not report any warnings that are mentioned in it.
#### Special comment
Individual lines of code can be excluded from checking by adding the following comment to the line:
// clang_sa_ignore [] []
Copy to clipboard
`` specifies a checker, package, or list (see [Manage checkers](https://docs.qualcomm.com/doc/80-N3040-23/topic/compiler-security-tools.html#hccpp-static-analyzer-manage-checkers-sub)) that is excluded from being applied to the line of code. It must be enclosed in square brackets. For example:
g_ptr = new int(0); // clang_sa_ignore [deadcode.DeadStores]
g_ptr = new int(0); // clang_sa_ignore [alpha] my comment text
g_ptr = new int(0); // clang_sa_ignore [alpha,deadcode.DeadStores]
Copy to clipboard
#### Preprocessor symbol
One or more lines of code can be conditionally excluded from all checking by using the preprocessor symbol `__clang_analyzer__`, which is automatically defined by the static analyzer. For example:
#ifndef __clang_analyzer__
// Code excluded from checking
#endif
Copy to clipboard
When using the preprocessor symbol with the static analyzer, the code must remain compilable, even though it is not required to be linkable or executable. For example, to exclude the body of a function from being analyzed, use the following conditional code:
#ifdef __clang_analyzer__
void noisyFunction(); // this version is for analysis only
#else // __clang_analyzer__
static void noisyFunction() {
// function body is generating too many false positives
}
#endif // __clang_analyzer__
Copy to clipboard
#### Function attribute
A common source of false positives is non-returning functions such as assert functions.
Although the static analyzer is aware of the standard library non-returning functions, if (for example) a program has its own implementation of asserts, it helps to mark them with the following function attribute:
__attribute__((__noreturn__))
Copy to clipboard
Using this attribute greatly improves the static analysis diagnostics and lessens the number of false positives. For example:
void my_abort(const char* msg) __attribute__((__noreturn__)) {
printf("%s", msg);
exit(1);
}
Copy to clipboard
#### Postprocess blacklist file
The blacklist file consists of row-wise indications of warnings that must be silenced. It uniquely identifies each warning by filename, function name, and bug description. Place this file in a network location that is accessible to all developer machines using the analyzer.
During postprocessing, identify the blacklist file through the `--blacklist-file ` flag. The post-process script does not report the bugs marked in this file. Besides silencing warnings across developer machines, this mechanism also allows you to silence warnings across build variants.
The blacklist file contains row-by-row warnings in the following format:
Copy to clipboard
For example:
>
>
> test.cpp foo Address of stack memory associated with local variable buff returned to caller [core.StackAddressEscape]
### Create whitelist directories
Often, unwieldy build systems make it impossible to turn on the static analyzer for only some subdirectories. For example, given the following hierarchy, assume you want to see results for only the `Qcomm_code` directories and not the `Open_source` directory:
ANDROID
Open_source Qcomm_hardware_code Qcomm_software_code
Copy to clipboard
The build system employed here allows only cflags to be set at a global level. In this case, create a whitelist file containing row-wise entries of the folders to be scanned. For example:
ANDROID/Qcomm_hardware_code
ANDROID/Qcomm_software_code
Copy to clipboard
The post-process script must be notified of the whitelist file through the flag, `--whitelist-file `. The script then identifies the row-wise entries and checks them against any static analysis warnings found. If none of the entries are a substring of the file location of a specific bug, that bug is silenced. Thus, having only `Qcomm_hardware_code` and `Qcomm_software_code` in the whitelist file will suffice because they will both be part of the location of the warnings you are interested in.
### Treat warnings as errors
Static analysis warnings can be treated as errors by appending the `-analyzer-werror flag` to the build flags. For example:
hexagon-clang --compile-and-analyze -Xclang -analyzer-werror test.c
Copy to clipboard
### Checker categorization by priority
Because checkers fall under two major priority categories (`high` and `medium`), the following flags are available in addition to the regular `--compile-and-analyze` flag:
--compile-and-analyze-high
Copy to clipboard
Allow only a small subset of checkers to be turned on.
These checkers are security critical and have an extremely low false positive rate. Teams adopting this tool should start with the `high` flag.
--compile-and-analyze-medium
Copy to clipboard
Slightly more permissive than the high flag.
The `medium` flag contains a few more checkers that are deemed security critical but have a slightly higher false positive rate.
### Performance mode
The static analyzer can be run in Performance mode. This mode prevents the creation of all the raw HTML files, and instead it displays a summary of the warnings in the console output.
To enable this mode, append the `--analyzer-perf` flag to the `--compile-and-analyze` flag in place of the `` option. For example:
hexagon-clang --compile-and-analyze --analyzer-perf test.c
hexagon-clang --compile-and-analyze-high --analyzer-perf test.c
Copy to clipboard
### YAML configuration file
The static analyzer can also be configured using a single configuration file (`--qc-config- file`) that combines all previously mentioned options in a single location. For example:
hexagon-clang --qc-config-file qc_sa_config.txt test.c
Copy to clipboard
The configuration file uses YAML format and is subject to all syntax restrictions. Following is a sample configuration file with embedded comments.
#############################################
# Static Analyzer configuration file #
#############################################
#############################################
# Global SA options #
#############################################
---
entry-type: global_settings
# Verbosity suppression level. Most useful is "high" i.e. "high suppression" == fewer false positives. The "high" setting here is equivalent to the command line compile-and-analyze-high flag.
# Available options: zero|default|high|medium|low
verbosity: high
# Location for individual reports. Absolute or relative path.
analyzer-output-dir: sa_report_dir
# Format for output reports. Most useful html.
analyzer-output-format: html
# Same as -analyzer-config stable-report-filename=true reduces the number of duplicate reports
stable-report-filename: true
# Do not output duplicate report for different path to the same location.
# The same header file can be included from multiple .c/cpp locations - report issues only once.
no-duplicate-reports: true
#############################################
# Per-checker individual options #
# It is applied _after_ the GLOBAL settings #
#############################################
---
entry-type: checker_config
config:
- package: core
# "default" - use verbosity setting from global_settings
# "on" - enable checker
# "off" - disable checker
checkers:
# Check for dereferences of null pointers
- checker-name: NullDereference
state: off
# Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers)
- checker-name: CallAndMessage
state: off
- package: alpha.core
checkers:
# Check when casting a malloc'ed type T, whether the size is a multiple of the size of T
- checker-name: CastSize
state: default
# Here follows the full list of all available packages and checkers with individual settings for each.
#############################################
# Individual files to skip during SA #
#############################################
---
entry-type: suppression_list
# Blacklist file. See -analyzer-suppression-file option for details
analyzer-suppression-file: suppression_file
# Per path report suppression. If any part of the file path matches this list - no report is generated. Currently there is no wildcard support.
suppress-path:
- modem_proc/audio_avs/main/voice/algos/mmecns/mmecns_lib/src
- modem_proc/audio_avs
...
Copy to clipboard
## Postprocessor
The postprocessor is a report generator that is implemented as a standalone script. This `post-process` script creates a summary of the report that is generated by using the `--compile-and-analyze` option (see [Static analyzer](https://docs.qualcomm.com/doc/80-N3040-23/topic/compiler-security-tools.html#hccpp-compiler-security-static-analyzer)). To invoke the postprocessor, enter the following command:
post-process --report-dir
Copy to clipboard
The postprocessor reads all the files from the directory specified by the `--report-dir` option and writes in the same directory a summary report file named `index.html`. The report title can be specified with the `--html-title`` option. For more information on the postprocessor, enter the `post-process --help` command.
The `post-process` script is stored in the `$INSTALL_PREFIX/bin` directory.
Note
In some cases the static analyzer might generate multiple report files for the same bug. The postprocessor cleans up after multiple report files. For this reason, run it regularly to keep the report directory clean.
Last Published: Oct 06, 2026
[Previous Topic
Verify the section assignment](https://docs.qualcomm.com/bundle/publicresource/80-N3040-23/topics/code-optimization.md) [Next Topic
Port code from GCC](https://docs.qualcomm.com/bundle/publicresource/80-N3040-23/topics/port-code-from-gcc.md)