Skip to content

[NFC][analyzer] Document configuration options #135169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 14, 2025
28 changes: 28 additions & 0 deletions clang/docs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -143,6 +143,34 @@ if (LLVM_ENABLE_SPHINX)
gen_rst_file_from_td(DiagnosticsReference.rst -gen-diag-docs ../include/clang/Basic/Diagnostic.td "${docs_targets}")
gen_rst_file_from_td(ClangCommandLineReference.rst -gen-opt-docs ../include/clang/Driver/ClangOptionDocs.td "${docs_targets}")

# Another generated file from a different source
set(docs_tools_dir ${CMAKE_CURRENT_SOURCE_DIR}/tools)
set(aopts_rst_rel_path analyzer/user-docs/Options.rst)
set(aopts_rst "${CMAKE_CURRENT_BINARY_DIR}/${aopts_rst_rel_path}")
set(analyzeroptions_def "${CMAKE_CURRENT_SOURCE_DIR}/../include/clang/StaticAnalyzer/Core/AnalyzerOptions.def")
set(aopts_rst_in "${CMAKE_CURRENT_SOURCE_DIR}/${aopts_rst_rel_path}.in")
add_custom_command(
OUTPUT ${aopts_rst}
COMMAND ${Python3_EXECUTABLE} generate_analyzer_options_docs.py
--options-def "${analyzeroptions_def}"
--template "${aopts_rst_in}"
--out "${aopts_rst}"
WORKING_DIRECTORY ${docs_tools_dir}
VERBATIM
COMMENT "Generating ${aopts_rst}"
DEPENDS ${docs_tools_dir}/${generate_aopts_docs}
${aopts_rst_in}
copy-clang-rst-docs
)
add_custom_target(generate-analyzer-options-rst DEPENDS ${aopts_rst})
foreach(target ${docs_targets})
add_dependencies(${target} generate-analyzer-options-rst)
endforeach()

# Technically this is redundant because generate-analyzer-options-rst
# depends on the copy operation (because it wants to drop a generated file
# into a subdirectory of the copied tree), but I'm leaving it here for the
# sake of clarity.
foreach(target ${docs_targets})
add_dependencies(${target} copy-clang-rst-docs)
endforeach()
1 change: 1 addition & 0 deletions clang/docs/analyzer/user-docs.rst
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ Contents:

user-docs/Installation
user-docs/CommandLineUsage
user-docs/Options
user-docs/UsingWithXCode
user-docs/FilingBugs
user-docs/CrossTranslationUnit
2 changes: 2 additions & 0 deletions clang/docs/analyzer/user-docs/CommandLineUsage.rst
Original file line number Diff line number Diff line change
@@ -194,6 +194,8 @@ When compiling your application to run on the simulator, it is important that **

If you aren't certain which compiler Xcode uses to build your project, try just running ``xcodebuild`` (without **scan-build**). You should see the full path to the compiler that Xcode is using, and use that as an argument to ``--use-cc``.

.. _command-line-usage-CodeChecker:

CodeChecker
-----------

114 changes: 114 additions & 0 deletions clang/docs/analyzer/user-docs/Options.rst.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
========================
Configuring the Analyzer
========================

The clang static analyzer supports two kinds of options:

1. Global **analyzer options** influence the behavior of the analyzer engine.
They are documented on this page, in the section :ref:`List of analyzer
options<list-of-analyzer-options>`.
2. The **checker options** belong to individual checkers (e.g.
``core.BitwiseShift:Pedantic`` and ``unix.Stream:Pedantic`` are completely
separate options) and customize the behavior of that particular checker.
These are documented within the documentation of each individual checker at
:doc:`../checkers`.

Assigning values to options
===========================

With the compiler frontend
--------------------------

All options can be configured by using the ``-analyzer-config`` flag of ``clang
-cc1`` (the so-called *compiler frontend* part of clang). The values of the
options are specified with the syntax ``-analyzer-config
OPT=VAL,OPT2=VAL2,...`` which supports specifying multiple options, but
separate flags like ``-analyzer-config OPT=VAL -analyzer-config OPT2=VAL2`` are
also accepted (with equivalent behavior). Analyzer options and checker options
can be freely intermixed here because it's easy to recognize that checker
option names are always prefixed with ``some.groups.NameOfChecker:``.

.. warning::
This is an internal interface, one should prefer `clang --analyze ...` for
regular use. Clang does not intend to preserve backwards compatibility or
announce breaking changes within the flags accepted by ``clang -cc1``
(but ``-analyzer-config`` survived many years without major changes).

With the clang driver
---------------------

In a conventional workflow ``clang -cc1`` (which is a low-level internal
interface) is invoked indirectly by the clang *driver* (i.e. plain ``clang``
without the ``-cc1`` flag), which acts as an "even more frontend" wrapper layer
around the ``clang -cc1`` *compiler frontend*. In this situation **each**
command line argument intended for the *compiler frontend* must be prefixed
with ``-Xclang``.

For example the following command analyzes ``foo.c`` in :ref:`shallow mode
<analyzer-option-mode>` with :ref:`loop unrolling
<analyzer-option-unroll-loops>`:

::

clang --analyze -Xclang -analyzer-config -Xclang mode=shallow,unroll-loops=true foo.c

When this is executed, the *driver* will compose and execute the following
``clang -cc1`` command (which can be inspected by passing the ``-v`` flag to
the *driver*):

::

clang -cc1 -analyze [...] -analyzer-config mode=shallow,unroll-loops=true foo.c

Here ``[...]`` stands for dozens of low-level flags which ensure that ``clang
-cc1`` does the right thing (e.g. ``-fcolor-diagnostics`` when it's suitable;
``-analyzer-checker`` flags to enable the default set of checkers). Also
note the distinction that the ``clang`` *driver* requires ``--analyze`` (double
dashes) while the ``clang -cc1`` *compiler frontend* requires ``-analyze``
(single dash).

.. note::
The flag ``-Xanalyzer`` is equivalent to ``-Xclang`` in these situations
(but doesn't forward other options of the clang frontend).

With CodeChecker
----------------

If the analysis is performed through :ref:`CodeChecker
<command-line-usage-CodeChecker>` (which e.g. supports the analysis of a whole
project instead of a single file) then it will act as another indirection
layer. CodeChecker provides separate command-line flags called
``--analyzer-config`` (for analyzer options) and ``--checker-config`` (for
checker options):

::

CodeChecker analyze -o outdir --checker-config clangsa:unix.Stream:Pedantic=true \
--analyzer-config clangsa:mode=shallow clangsa:unroll-loops=true \
-- compile_commands.json

These CodeChecker flags may be followed by multiple ``OPT=VAL`` pairs as
separate arguments (and this is why the example needs to use ``--`` before
``compile_commands.json``). The option names are all prefixed with ``clangsa:``
to ensure that they are passed to the clang static analyzer (and not other
analyzer tools that are also supported by CodeChecker).

.. _list-of-analyzer-options:

List of analyzer options
========================

.. warning::
These options are primarily intended for development purposes and
non-default values are usually unsupported. Changing their values may
drastically alter the behavior of the analyzer, and may even result in
instabilities or crashes! Crash reports are welcome and depending on the
severity they may be fixed.

..
The contents of this section are automatically generated by the script
clang/docs/tools/generate_analyzer_options_docs.py from the header file
AnalyzerOptions.def to ensure that the RST/web documentation is synchronized
with the command line help options.

.. OPTIONS_LIST_PLACEHOLDER
Loading