summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/AutomaticReferenceCounting.rst2
-rw-r--r--docs/ClangCommandLineReference.rst2
-rw-r--r--docs/ClangFormat.rst17
-rw-r--r--docs/ClangFormatStyleOptions.rst183
-rw-r--r--docs/ClangPlugins.rst4
-rw-r--r--docs/ClangStaticAnalyzer.rst19
-rw-r--r--docs/ClangTools.rst19
-rw-r--r--docs/ControlFlowIntegrity.rst2
-rw-r--r--docs/ControlFlowIntegrityDesign.rst8
-rw-r--r--docs/ExternalClangExamples.rst6
-rw-r--r--docs/HardwareAssistedAddressSanitizerDesign.rst5
-rw-r--r--docs/HowToSetupToolingForLLVM.rst2
-rw-r--r--docs/InternalsManual.rst22
-rw-r--r--docs/IntroductionToTheClangAST.rst2
-rw-r--r--docs/JSONCompilationDatabase.rst2
-rw-r--r--docs/LanguageExtensions.rst231
-rw-r--r--docs/LibASTMatchersReference.html316
-rw-r--r--docs/LibASTMatchersTutorial.rst25
-rw-r--r--docs/LibTooling.rst10
-rw-r--r--docs/MSVCCompatibility.rst4
-rw-r--r--docs/OpenMPSupport.rst83
-rw-r--r--docs/PCHInternals.rst2
-rw-r--r--docs/ReleaseNotes.rst242
-rw-r--r--docs/SafeStack.rst16
-rw-r--r--docs/SanitizerCoverage.rst14
-rw-r--r--docs/ShadowCallStack.rst210
-rw-r--r--docs/ThreadSanitizer.rst6
-rw-r--r--docs/Toolchain.rst30
-rw-r--r--docs/UndefinedBehaviorSanitizer.rst2
-rw-r--r--docs/UsersManual.rst62
-rw-r--r--docs/analyzer/checkers.rst2034
-rw-r--r--docs/analyzer/checkers/callandmessage_example.c66
-rw-r--r--docs/analyzer/checkers/dealloc_example.m49
-rw-r--r--docs/analyzer/checkers/dividezero_example.c9
-rw-r--r--docs/analyzer/checkers/mismatched_deallocator_example.cpp56
-rw-r--r--docs/analyzer/checkers/newdelete_example.cpp41
-rw-r--r--docs/analyzer/checkers/seckeychainapi_example.m64
-rw-r--r--docs/analyzer/checkers/unix_api_example.c37
-rw-r--r--docs/analyzer/checkers/unix_malloc_example.c30
-rw-r--r--docs/analyzer/developer-docs.rst14
-rw-r--r--docs/analyzer/developer-docs/DebugChecks.rst (renamed from docs/analyzer/DebugChecks.rst)7
-rw-r--r--docs/analyzer/developer-docs/IPA.rst (renamed from docs/analyzer/IPA.txt)92
-rw-r--r--docs/analyzer/developer-docs/InitializerLists.rst (renamed from docs/analyzer/DesignDiscussions/InitializerLists.rst)162
-rw-r--r--docs/analyzer/developer-docs/RegionStore.rst (renamed from docs/analyzer/RegionStore.txt)100
-rw-r--r--docs/analyzer/developer-docs/nullability.rst (renamed from docs/analyzer/nullability.rst)131
-rw-r--r--docs/analyzer/index.rst23
-rw-r--r--docs/conf.py6
-rw-r--r--docs/index.rst1
48 files changed, 3679 insertions, 791 deletions
diff --git a/docs/AutomaticReferenceCounting.rst b/docs/AutomaticReferenceCounting.rst
index 3e51d2f5d7..746c445f90 100644
--- a/docs/AutomaticReferenceCounting.rst
+++ b/docs/AutomaticReferenceCounting.rst
@@ -9,7 +9,7 @@
/*
* Automatic numbering is described in this article:
- * http://dev.opera.com/articles/view/automatic-numbering-with-css-counters/
+ * https://dev.opera.com/articles/view/automatic-numbering-with-css-counters/
*/
/*
* Automatic numbering for the TOC.
diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst
index e852c3e387..f153a0cd07 100644
--- a/docs/ClangCommandLineReference.rst
+++ b/docs/ClangCommandLineReference.rst
@@ -2610,6 +2610,8 @@ X86
.. option:: -mavx512bitalg, -mno-avx512bitalg
+.. option:: -mavx512bf16, -mno-avx512bf16
+
.. option:: -mavx512bw, -mno-avx512bw
.. option:: -mavx512cd, -mno-avx512cd
diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst
index f2228c5750..c1347f3070 100644
--- a/docs/ClangFormat.rst
+++ b/docs/ClangFormat.rst
@@ -11,12 +11,12 @@ Standalone Tool
===============
:program:`clang-format` is located in `clang/tools/clang-format` and can be used
-to format C/C++/Java/JavaScript/Objective-C/Protobuf code.
+to format C/C++/Java/JavaScript/Objective-C/Protobuf/C# code.
.. code-block:: console
$ clang-format -help
- OVERVIEW: A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf code.
+ OVERVIEW: A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf/C# code.
If no arguments are specified, it formats the code from standard input
and writes the result to the standard output.
@@ -165,6 +165,19 @@ menu item by renaming the script, and can assign the menu item a keyboard
shortcut in the BBEdit preferences, under Menus & Shortcuts.
+CLion Integration
+==================
+
+:program:`clang-format` is integrated into `CLion <https://www.jetbrains
+.com/clion/>`_ as an alternative code formatter. It is disabled by default and
+can be turned on in Settings/Preferences | Editor | Code Style.
+
+If :program:`clang-format` support is enabled, CLion detects config files when
+opening a project and suggests overriding the current IDE settings. Code style
+rules from the ``.clang-format`` files are then applied automatically to all
+editor actions, including auto-completion, code generation, and refactorings.
+
+
Visual Studio Integration
=========================
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index 054d5c32c6..3611bdd7b0 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -7,8 +7,8 @@ supported by :doc:`LibFormat` and :doc:`ClangFormat`.
When using :program:`clang-format` command line utility or
``clang::format::reformat(...)`` functions from code, one can either use one of
-the predefined styles (LLVM, Google, Chromium, Mozilla, WebKit) or create a
-custom style by configuring specific style options.
+the predefined styles (LLVM, Google, Chromium, Mozilla, WebKit, Microsoft) or
+create a custom style by configuring specific style options.
Configuring Style with clang-format
@@ -68,6 +68,10 @@ An example of a configuration file for multiple languages:
Language: Proto
# Don't format .proto files.
DisableFormat: true
+ ---
+ Language: CSharp
+ # Use 100 columns for C#.
+ ColumnLimit: 100
...
An easy way to get a valid ``.clang-format`` file containing all configuration
@@ -137,13 +141,16 @@ the configuration (without a prefix: ``Auto``).
<http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml>`_
* ``Chromium``
A style complying with `Chromium's style guide
- <http://www.chromium.org/developers/coding-style>`_
+ <https://www.chromium.org/developers/coding-style>`_
* ``Mozilla``
A style complying with `Mozilla's style guide
<https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style>`_
* ``WebKit``
A style complying with `WebKit's style guide
- <http://www.webkit.org/coding/coding-style.html>`_
+ <https://www.webkit.org/coding/coding-style.html>`_
+ * ``Microsoft``
+ A style complying with `Microsoft's style guide
+ <https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017>`_
.. START_FORMAT_STYLE_OPTIONS
@@ -270,6 +277,41 @@ the configuration (without a prefix: ``Auto``).
int a; // My comment a vs. int a; // My comment a
int b = 2; // comment b int b = 2; // comment about b
+**AllowAllArgumentsOnNextLine** (``bool``)
+ If a function call or braced initializer list doesn't fit on a
+ line, allow putting all arguments onto the next line, even if
+ ``BinPackArguments`` is ``false``.
+
+ .. code-block:: c++
+
+ true:
+ callFunction(
+ a, b, c, d);
+
+ false:
+ callFunction(a,
+ b,
+ c,
+ d);
+
+**AllowAllConstructorInitializersOnNextLine** (``bool``)
+ If a constructor definition with a member initializer list doesn't
+ fit on a single line, allow putting all member initializers onto the next
+ line, if ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is true.
+ Note that this parameter has no effect if
+ ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is false.
+
+ .. code-block:: c++
+
+ true:
+ MyClass::MyClass() :
+ member0(0), member1(2) {}
+
+ false:
+ MyClass::MyClass() :
+ member0(0),
+ member1(2) {}
+
**AllowAllParametersOfDeclarationOnNextLine** (``bool``)
If the function declaration doesn't fit on a line,
allow putting all parameters of a function declaration onto
@@ -367,9 +409,84 @@ the configuration (without a prefix: ``Auto``).
-**AllowShortIfStatementsOnASingleLine** (``bool``)
+**AllowShortIfStatementsOnASingleLine** (``ShortIfStyle``)
If ``true``, ``if (a) return;`` can be put on a single line.
+ Possible values:
+
+ * ``SIS_Never`` (in configuration: ``Never``)
+ Never put short ifs on the same line.
+
+ .. code-block:: c++
+
+ if (a)
+ return ;
+ else {
+ return;
+ }
+
+ * ``SIS_WithoutElse`` (in configuration: ``WithoutElse``)
+ Without else put short ifs on the same line only if
+ the else is not a compound statement.
+
+ .. code-block:: c++
+
+ if (a) return;
+ else
+ return;
+
+ * ``SIS_Always`` (in configuration: ``Always``)
+ Always put short ifs on the same line if
+ the else is not a compound statement or not.
+
+ .. code-block:: c++
+
+ if (a) return;
+ else {
+ return;
+ }
+
+
+
+**AllowShortLambdasOnASingleLine** (``ShortLambdaStyle``)
+ Dependent on the value, ``auto lambda []() { return 0; }`` can be put on a
+ single line.
+
+ Possible values:
+
+ * ``SLS_None`` (in configuration: ``None``)
+ Never merge lambdas into a single line.
+
+ * ``SLS_Empty`` (in configuration: ``Empty``)
+ Only merge empty lambdas.
+
+ .. code-block:: c++
+
+ auto lambda = [](int a) {}
+ auto lambda2 = [](int a) {
+ return a;
+ };
+
+ * ``SLS_Inline`` (in configuration: ``Inline``)
+ Merge lambda into a single line if argument of a function.
+
+ .. code-block:: c++
+
+ auto lambda = [](int a) {
+ return a;
+ };
+ sort(a.begin(), a.end(), ()[] { return x < y; })
+
+ * ``SLS_All`` (in configuration: ``All``)
+ Merge all lambdas fitting on a single line.
+
+ .. code-block:: c++
+
+ auto lambda = [](int a) {}
+ auto lambda2 = [](int a) { return a; };
+
+
+
**AllowShortLoopsOnASingleLine** (``bool``)
If ``true``, ``while (true) continue;`` can be put on a single
line.
@@ -587,6 +704,23 @@ the configuration (without a prefix: ``Auto``).
Nested configuration flags:
+ * ``bool AfterCaseLabel`` Wrap case labels.
+
+ .. code-block:: c++
+
+ false: true:
+ switch (foo) { vs. switch (foo) {
+ case 1: { case 1:
+ bar(); {
+ break; bar();
+ } break;
+ default: { }
+ plop(); default:
+ } {
+ } plop();
+ }
+ }
+
* ``bool AfterClass`` Wrap class definitions.
.. code-block:: c++
@@ -1212,7 +1346,7 @@ the configuration (without a prefix: ``Auto``).
true: false:
namespace a { vs. namespace a {
foo(); foo();
- } // namespace a; }
+ } // namespace a }
**ForEachMacros** (``std::vector<std::string>``)
A vector of macros that should be interpreted as foreach loops
@@ -1278,7 +1412,7 @@ the configuration (without a prefix: ``Auto``).
used for ordering ``#includes``.
`POSIX extended
- <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
+ <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
regular expressions are supported.
These regular expressions are matched against the filename of an include
@@ -1365,6 +1499,17 @@ the configuration (without a prefix: ``Auto``).
# endif
#endif
+ * ``PPDIS_BeforeHash`` (in configuration: ``BeforeHash``)
+ Indents directives before the hash.
+
+ .. code-block:: c++
+
+ #if FOO
+ #if BAR
+ #include <foo>
+ #endif
+ #endif
+
**IndentWidth** (``unsigned``)
@@ -1496,6 +1641,9 @@ the configuration (without a prefix: ``Auto``).
* ``LK_Cpp`` (in configuration: ``Cpp``)
Should be used for C, C++.
+ * ``LK_CSharp`` (in configuration: ``CSharp``)
+ Should be used for C#.
+
* ``LK_Java`` (in configuration: ``Java``)
Should be used for Java.
@@ -1812,6 +1960,14 @@ the configuration (without a prefix: ``Auto``).
true: false:
(int) i; vs. (int)i;
+**SpaceAfterLogicalNot** (``bool``)
+ If ``true``, a space is inserted after the logical not operator (``!``).
+
+ .. code-block:: c++
+
+ true: false:
+ ! someExpression(); vs. !someExpression();
+
**SpaceAfterTemplateKeyword** (``bool``)
If ``true``, a space will be inserted after the 'template' keyword.
@@ -1886,6 +2042,19 @@ the configuration (without a prefix: ``Auto``).
}
}
+ * ``SBPO_NonEmptyParentheses`` (in configuration: ``NonEmptyParentheses``)
+ Put a space before opening parentheses only if the parentheses are not
+ empty i.e. '()'
+
+ .. code-block:: c++
+
+ void() {
+ if (true) {
+ f();
+ g (x, y, z);
+ }
+ }
+
* ``SBPO_Always`` (in configuration: ``Always``)
Always put a space before opening parentheses, except when it's
prohibited by the syntax rules (in function-like macro definitions) or
diff --git a/docs/ClangPlugins.rst b/docs/ClangPlugins.rst
index 5e6082e903..8d954407a4 100644
--- a/docs/ClangPlugins.rst
+++ b/docs/ClangPlugins.rst
@@ -69,7 +69,7 @@ Putting it all together
Let's look at an example plugin that prints top-level function names. This
example is checked into the clang repository; please take a look at
the `latest version of PrintFunctionNames.cpp
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/PrintFunctionNames.cpp?view=markup>`_.
+<https://github.com/llvm/llvm-project/blob/master/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp>`_.
Running the plugin
==================
@@ -110,7 +110,7 @@ source tree:
-plugin -Xclang print-fns
Also see the print-function-name plugin example's
-`README <https://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/README.txt?view=markup>`_
+`README <https://github.com/llvm/llvm-project/blob/master/clang/examples/PrintFunctionNames/README.txt>`_
Using the clang command line
diff --git a/docs/ClangStaticAnalyzer.rst b/docs/ClangStaticAnalyzer.rst
new file mode 100644
index 0000000000..f18fd81384
--- /dev/null
+++ b/docs/ClangStaticAnalyzer.rst
@@ -0,0 +1,19 @@
+=====================
+Clang Static Analyzer
+=====================
+
+The Clang Static Analyzer is a source code analysis tool that finds bugs in C, C++, and Objective-C programs.
+It implements *path-sensitive*, *inter-procedural analysis* based on *symbolic execution* technique.
+
+This is the Static Analyzer documentation page.
+
+See the `Official Tool Page <https://clang-analyzer.llvm.org/>`_.
+
+.. toctree::
+ :caption: Table of Contents
+ :numbered:
+ :maxdepth: 2
+
+ analyzer/checkers
+ analyzer/developer-docs
+
diff --git a/docs/ClangTools.rst b/docs/ClangTools.rst
index 99e8a5e4f6..bc30459957 100644
--- a/docs/ClangTools.rst
+++ b/docs/ClangTools.rst
@@ -9,22 +9,9 @@ functionality such as fast syntax checking, automatic formatting,
refactoring, etc.
Only a couple of the most basic and fundamental tools are kept in the
-primary Clang Subversion project. The rest of the tools are kept in a
-side-project so that developers who don't want or need to build them
-don't. If you want to get access to the extra Clang Tools repository,
-simply check it out into the tools tree of your Clang checkout and
-follow the usual process for building and working with a combined
-LLVM/Clang checkout:
-
-- With Subversion:
-
- - ``cd llvm/tools/clang/tools``
- - ``svn co https://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra``
-
-- Or with Git:
-
- - ``cd llvm/tools/clang/tools``
- - ``git clone https://llvm.org/git/clang-tools-extra.git extra``
+primary Clang tree. The rest of the tools are kept in a separate
+directory tree, `clang-tools-extra
+<https://github.com/llvm/llvm-project/tree/master/clang-tools-extra>`_.
This document describes a high-level overview of the organization of
Clang Tools within the project as well as giving an introduction to some
diff --git a/docs/ControlFlowIntegrity.rst b/docs/ControlFlowIntegrity.rst
index b0b37f83f1..f57bdf5d2c 100644
--- a/docs/ControlFlowIntegrity.rst
+++ b/docs/ControlFlowIntegrity.rst
@@ -335,7 +335,7 @@ Please refer to the :doc:`design document<ControlFlowIntegrityDesign>`.
Publications
============
-`Control-Flow Integrity: Principles, Implementations, and Applications <http://research.microsoft.com/pubs/64250/ccs05.pdf>`_.
+`Control-Flow Integrity: Principles, Implementations, and Applications <https://research.microsoft.com/pubs/64250/ccs05.pdf>`_.
Martin Abadi, Mihai Budiu, Úlfar Erlingsson, Jay Ligatti.
`Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM <http://www.pcc.me.uk/~peter/acad/usenix14.pdf>`_.
diff --git a/docs/ControlFlowIntegrityDesign.rst b/docs/ControlFlowIntegrityDesign.rst
index bb1770da5a..076713201a 100644
--- a/docs/ControlFlowIntegrityDesign.rst
+++ b/docs/ControlFlowIntegrityDesign.rst
@@ -92,7 +92,7 @@ The compiler relies on co-operation from the linker in order to assemble
the bit vectors for the whole program. It currently does this using LLVM's
`type metadata`_ mechanism together with link-time optimization.
-.. _address point: http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
+.. _address point: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
.. _type metadata: https://llvm.org/docs/TypeMetadata.html
.. _ByteArrayBuilder: https://llvm.org/docs/doxygen/html/structllvm_1_1ByteArrayBuilder.html
@@ -196,7 +196,7 @@ those sub-hierarchies need to be (see "Stripping Leading/Trailing Zeros in Bit
Vectors" above). The `GlobalLayoutBuilder`_ class is responsible for laying
out the globals efficiently to minimize the sizes of the underlying bitsets.
-.. _GlobalLayoutBuilder: https://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/LowerTypeTests.h?view=markup
+.. _GlobalLayoutBuilder: https://github.com/llvm/llvm-project/blob/master/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
Alignment
~~~~~~~~~
@@ -300,7 +300,7 @@ The interleaving scheme, however, can only work with individual virtual tables s
In comparison, the old scheme does not require the splitting but it is more efficient when the combined virtual tables have been split.
The `GlobalSplit`_ pass is responsible for splitting combined virtual tables into individual ones.
-.. _GlobalSplit: https://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalSplit.cpp?view=markup
+.. _GlobalSplit: https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/IPO/GlobalSplit.cpp
Order virtual tables by a pre-order traversal of the class hierarchy
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -746,7 +746,7 @@ RCFI does not protect `RET` instructions:
* embedded into other instructions (e.g. `0f4fc3 cmovg %ebx,%eax`).
.. _SafeStack: https://clang.llvm.org/docs/SafeStack.html
-.. _RFG: http://xlab.tencent.com/en/2016/11/02/return-flow-guard
+.. _RFG: https://xlab.tencent.com/en/2016/11/02/return-flow-guard
.. _Intel CET: https://software.intel.com/en-us/blogs/2016/06/09/intel-release-new-technology-specifications-protect-rop-attacks
Hardware support
diff --git a/docs/ExternalClangExamples.rst b/docs/ExternalClangExamples.rst
index b92fa3fcc0..58c605a9a8 100644
--- a/docs/ExternalClangExamples.rst
+++ b/docs/ExternalClangExamples.rst
@@ -20,7 +20,7 @@ where Clang is used are:
If you know of (or wrote!) a tool or project using Clang, please send an
email to Clang's `development discussion mailing list
-<http://lists.llvm.org/mailman/listinfo/cfe-dev>`_ to have it added.
+<https://lists.llvm.org/mailman/listinfo/cfe-dev>`_ to have it added.
(or if you are already a Clang contributor, feel free to directly commit
additions). Since the primary purpose of this page is to provide examples
that can help developers, generally they must have code available.
@@ -33,7 +33,7 @@ List of projects and tools
a persistent in-memory database of references, symbolnames, completions
etc."
-`<http://rprichard.github.com/sourceweb/>`_
+`<https://rprichard.github.com/sourceweb/>`_
"A C/C++ source code indexer and navigator"
`<https://github.com/etaoins/qconnectlint>`_
@@ -42,7 +42,7 @@ List of projects and tools
`<https://github.com/woboq/woboq_codebrowser>`_
"The Woboq Code Browser is a web-based code browser for C/C++ projects.
- Check out `<http://code.woboq.org/>`_ for an example!"
+ Check out `<https://code.woboq.org/>`_ for an example!"
`<https://github.com/mozilla/dxr>`_
"DXR is a source code cross-reference tool that uses static analysis
diff --git a/docs/HardwareAssistedAddressSanitizerDesign.rst b/docs/HardwareAssistedAddressSanitizerDesign.rst
index 4e6f5d14cd..12e2cc2525 100644
--- a/docs/HardwareAssistedAddressSanitizerDesign.rst
+++ b/docs/HardwareAssistedAddressSanitizerDesign.rst
@@ -131,7 +131,8 @@ HWASAN:
https://www.kernel.org/doc/Documentation/arm64/tagged-pointers.txt).
* **Does not require redzones to detect buffer overflows**,
but the buffer overflow detection is probabilistic, with roughly
- `(2**TS-1)/(2**TS)` probability of catching a bug.
+ `1/(2**TS)` chance of missing a bug (6.25% or 0.39% with 4 and 8-bit TS
+ respectively).
* **Does not require quarantine to detect heap-use-after-free,
or stack-use-after-return**.
The detection is similarly probabilistic.
@@ -162,7 +163,7 @@ Related Work
* *TODO: add more "related work" links. Suggestions are welcome.*
-.. _Watchdog: http://www.cis.upenn.edu/acg/papers/isca12_watchdog.pdf
+.. _Watchdog: https://www.cis.upenn.edu/acg/papers/isca12_watchdog.pdf
.. _Effective and Efficient Memory Protection Using Dynamic Tainting: https://www.cc.gatech.edu/~orso/papers/clause.doudalis.orso.prvulovic.pdf
.. _SPARC ADI: https://lazytyped.blogspot.com/2017/09/getting-started-with-adi.html
.. _AddressSanitizer paper: https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf
diff --git a/docs/HowToSetupToolingForLLVM.rst b/docs/HowToSetupToolingForLLVM.rst
index 686aca840a..dfa199ec59 100644
--- a/docs/HowToSetupToolingForLLVM.rst
+++ b/docs/HowToSetupToolingForLLVM.rst
@@ -23,7 +23,7 @@ Setup Clang Tooling Using CMake and Make
========================================
If you intend to use make to build LLVM, you should have CMake 2.8.6 or
-later installed (can be found `here <http://cmake.org>`_).
+later installed (can be found `here <https://cmake.org>`_).
First, you need to generate Makefiles for LLVM with CMake. You need to
make a build directory and run CMake from it:
diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst
index b6b49d7547..0b180b95d5 100644
--- a/docs/InternalsManual.rst
+++ b/docs/InternalsManual.rst
@@ -534,7 +534,7 @@ token. This concept maps directly to the "spelling location" for the token.
``SourceRange`` and ``CharSourceRange``
---------------------------------------
-.. mostly taken from http://lists.llvm.org/pipermail/cfe-dev/2010-August/010595.html
+.. mostly taken from https://lists.llvm.org/pipermail/cfe-dev/2010-August/010595.html
Clang represents most source ranges by [first, last], where "first" and "last"
each point to the beginning of their respective tokens. For example consider
@@ -1364,7 +1364,7 @@ constructed for function bodies (usually an instance of ``CompoundStmt``), but
can also be instantiated to represent the control-flow of any class that
subclasses ``Stmt``, which includes simple expressions. Control-flow graphs
are especially useful for performing `flow- or path-sensitive
-<http://en.wikipedia.org/wiki/Data_flow_analysis#Sensitivities>`_ program
+<https://en.wikipedia.org/wiki/Data_flow_analysis#Sensitivities>`_ program
analyses on a given function.
Basic Blocks
@@ -1686,7 +1686,7 @@ semantic checking for some attributes, etc.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The first step to adding a new attribute to Clang is to add its definition to
`include/clang/Basic/Attr.td
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup>`_.
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/Attr.td>`_.
This tablegen definition must derive from the ``Attr`` (tablegen, not
semantic) type, or one of its derivatives. Most attributes will derive from the
``InheritableAttr`` type, which specifies that the attribute can be inherited by
@@ -1748,10 +1748,10 @@ the ``SubjectList``. The diagnostics generated for subject list violations are
either ``diag::warn_attribute_wrong_decl_type`` or
``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is found
in `include/clang/Sema/ParsedAttr.h
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedAttr.h?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Sema/ParsedAttr.h>`_
If a previously unused Decl node is added to the ``SubjectList``, the logic used
to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/utils/TableGen/ClangAttrEmitter.cpp>`_
may need to be updated.
By default, all subjects in the SubjectList must either be a Decl node defined
@@ -1773,7 +1773,7 @@ All attributes must have some form of documentation associated with them.
Documentation is table generated on the public web server by a server-side
process that runs daily. Generally, the documentation for an attribute is a
stand-alone definition in `include/clang/Basic/AttrDocs.td
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttdDocs.td?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/AttrDocs.td>`_
that is named after the attribute being documented.
If the attribute is not for public consumption, or is an implicitly-created
@@ -1824,7 +1824,7 @@ All arguments have a name and a flag that specifies whether the argument is
optional. The associated C++ type of the argument is determined by the argument
definition type. If the existing argument types are insufficient, new types can
be created, but it requires modifying `utils/TableGen/ClangAttrEmitter.cpp
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/utils/TableGen/ClangAttrEmitter.cpp>`_
to properly support the type.
Other Properties
@@ -1836,7 +1836,7 @@ document, however a few deserve mention.
If the parsed form of the attribute is more complex, or differs from the
semantic form, the ``HasCustomParsing`` bit can be set to ``1`` for the class,
and the parsing code in `Parser::ParseGNUAttributeArgs()
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/lib/Parse/ParseDecl.cpp>`_
can be updated for the special case. Note that this only applies to arguments
with a GNU spelling -- attributes with a __declspec spelling currently ignore
this flag and are handled by ``Parser::ParseMicrosoftDeclSpec``.
@@ -1899,7 +1899,7 @@ semantic attribute class object, with ``public`` access.
Boilerplate
^^^^^^^^^^^
All semantic processing of declaration attributes happens in `lib/Sema/SemaDeclAttr.cpp
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup>`_,
+<https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaDeclAttr.cpp>`_,
and generally starts in the ``ProcessDeclAttribute()`` function. If the
attribute is a "simple" attribute -- meaning that it requires no custom semantic
processing aside from what is automatically provided, add a call to
@@ -1915,11 +1915,11 @@ correct minimum number of arguments are passed, etc.
If the attribute adds additional warnings, define a ``DiagGroup`` in
`include/clang/Basic/DiagnosticGroups.td
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/DiagnosticGroups.td>`_
named after the attribute's ``Spelling`` with "_"s replaced by "-"s. If there
is only a single diagnostic, it is permissible to use ``InGroup<DiagGroup<"your-attribute">>``
directly in `DiagnosticSemaKinds.td
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/DiagnosticSemaKinds.td>`_
All semantic diagnostics generated for your attribute, including automatically-
generated ones (such as subjects and argument counts), should have a
diff --git a/docs/IntroductionToTheClangAST.rst b/docs/IntroductionToTheClangAST.rst
index f357c03507..286ab88d01 100644
--- a/docs/IntroductionToTheClangAST.rst
+++ b/docs/IntroductionToTheClangAST.rst
@@ -9,7 +9,7 @@ matchers.
.. raw:: html
- <center><iframe width="560" height="315" src="http://www.youtube.com/embed/VqCkCDFLSsc?vq=hd720" frameborder="0" allowfullscreen></iframe></center>
+ <center><iframe width="560" height="315" src="https://www.youtube.com/embed/VqCkCDFLSsc?vq=hd720" frameborder="0" allowfullscreen></iframe></center>
`Slides <https://llvm.org/devmtg/2013-04/klimek-slides.pdf>`_
diff --git a/docs/JSONCompilationDatabase.rst b/docs/JSONCompilationDatabase.rst
index 1f3441b033..b5766402e2 100644
--- a/docs/JSONCompilationDatabase.rst
+++ b/docs/JSONCompilationDatabase.rst
@@ -29,7 +29,7 @@ system is not necessarily the best solution:
Supported Systems
=================
-Currently `CMake <http://cmake.org>`_ (since 2.8.5) supports generation
+Currently `CMake <https://cmake.org>`_ (since 2.8.5) supports generation
of compilation databases for Unix Makefile builds (Ninja builds in the
works) with the option ``CMAKE_EXPORT_COMPILE_COMMANDS``.
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index e155cefb78..7772bf53e8 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -20,7 +20,7 @@ Introduction
This document describes the language extensions provided by Clang. In addition
to the language extensions listed here, Clang aims to support a broad range of
GCC extensions. Please see the `GCC manual
-<http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html>`_ for more information on
+<https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html>`_ for more information on
these extensions.
.. _langext-feature_check:
@@ -474,44 +474,58 @@ Half-Precision Floating Point
=============================
Clang supports two half-precision (16-bit) floating point types: ``__fp16`` and
-``_Float16``. ``__fp16`` is defined in the ARM C Language Extensions (`ACLE
-<http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053d/IHI0053D_acle_2_1.pdf>`_)
-and ``_Float16`` in ISO/IEC TS 18661-3:2015.
-
-``__fp16`` is a storage and interchange format only. This means that values of
-``__fp16`` promote to (at least) float when used in arithmetic operations.
-There are two ``__fp16`` formats. Clang supports the IEEE 754-2008 format and
-not the ARM alternative format.
-
-ISO/IEC TS 18661-3:2015 defines C support for additional floating point types.
-``_FloatN`` is defined as a binary floating type, where the N suffix denotes
-the number of bits and is 16, 32, 64, or greater and equal to 128 and a
-multiple of 32. Clang supports ``_Float16``. The difference from ``__fp16`` is
-that arithmetic on ``_Float16`` is performed in half-precision, thus it is not
-a storage-only format. ``_Float16`` is available as a source language type in
-both C and C++ mode.
-
-It is recommended that portable code use the ``_Float16`` type because
-``__fp16`` is an ARM C-Language Extension (ACLE), whereas ``_Float16`` is
-defined by the C standards committee, so using ``_Float16`` will not prevent
-code from being ported to architectures other than Arm. Also, ``_Float16``
-arithmetic and operations will directly map on half-precision instructions when
-they are available (e.g. Armv8.2-A), avoiding conversions to/from
-single-precision, and thus will result in more performant code. If
-half-precision instructions are unavailable, values will be promoted to
-single-precision, similar to the semantics of ``__fp16`` except that the
-results will be stored in single-precision.
-
-In an arithmetic operation where one operand is of ``__fp16`` type and the
-other is of ``_Float16`` type, the ``_Float16`` type is first converted to
-``__fp16`` type and then the operation is completed as if both operands were of
-``__fp16`` type.
-
-To define a ``_Float16`` literal, suffix ``f16`` can be appended to the compile-time
-constant declaration. There is no default argument promotion for ``_Float16``; this
-applies to the standard floating types only. As a consequence, for example, an
-explicit cast is required for printing a ``_Float16`` value (there is no string
-format specifier for ``_Float16``).
+``_Float16``. These types are supported in all language modes.
+
+``__fp16`` is supported on every target, as it is purely a storage format; see below.
+``_Float16`` is currently only supported on the following targets, with further
+targets pending ABI standardization:
+- 32-bit ARM
+- 64-bit ARM (AArch64)
+- SPIR
+``_Float16`` will be supported on more targets as they define ABIs for it.
+
+``__fp16`` is a storage and interchange format only. This means that values of
+``__fp16`` are immediately promoted to (at least) ``float`` when used in arithmetic
+operations, so that e.g. the result of adding two ``__fp16`` values has type ``float``.
+The behavior of ``__fp16`` is specified by the ARM C Language Extensions (`ACLE <http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053d/IHI0053D_acle_2_1.pdf>`_).
+Clang uses the ``binary16`` format from IEEE 754-2008 for ``__fp16``, not the ARM
+alternative format.
+
+``_Float16`` is an extended floating-point type. This means that, just like arithmetic on
+``float`` or ``double``, arithmetic on ``_Float16`` operands is formally performed in the
+``_Float16`` type, so that e.g. the result of adding two ``_Float16`` values has type
+``_Float16``. The behavior of ``_Float16`` is specified by ISO/IEC TS 18661-3:2015
+("Floating-point extensions for C"). As with ``__fp16``, Clang uses the ``binary16``
+format from IEEE 754-2008 for ``_Float16``.
+
+``_Float16`` arithmetic will be performed using native half-precision support
+when available on the target (e.g. on ARMv8.2a); otherwise it will be performed
+at a higher precision (currently always ``float``) and then truncated down to
+``_Float16``. Note that C and C++ allow intermediate floating-point operands
+of an expression to be computed with greater precision than is expressible in
+their type, so Clang may avoid intermediate truncations in certain cases; this may
+lead to results that are inconsistent with native arithmetic.
+
+It is recommended that portable code use ``_Float16`` instead of ``__fp16``,
+as it has been defined by the C standards committee and has behavior that is
+more familiar to most programmers.
+
+Because ``__fp16`` operands are always immediately promoted to ``float``, the
+common real type of ``__fp16`` and ``_Float16`` for the purposes of the usual
+arithmetic conversions is ``float``.
+
+A literal can be given ``_Float16`` type using the suffix ``f16``; for example:
+```
+3.14f16
+```
+
+Because default argument promotion only applies to the standard floating-point
+types, ``_Float16`` values are not promoted to ``double`` when passed as variadic
+or untyped arguments. As a consequence, some caution must be taken when using
+certain library facilities with ``_Float16``; for example, there is no ``printf`` format
+specifier for ``_Float16``, and (unlike ``float``) it will not be implicitly promoted to
+``double`` when passed to ``printf``, so the programmer must explicitly cast it to
+``double`` before using it with an ``%f`` or similar specifier.
Messages on ``deprecated`` and ``unavailable`` Attributes
=========================================================
@@ -1036,9 +1050,9 @@ the supported set of system headers, currently:
* The Microsoft standard C++ library
Clang supports the `GNU C++ type traits
-<http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html>`_ and a subset of the
+<https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html>`_ and a subset of the
`Microsoft Visual C++ Type traits
-<http://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx>`_.
+<https://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx>`_.
Feature detection is supported only for some of the primitives at present. User
code should not use these checks because they bear no direct relation to the
@@ -1354,7 +1368,7 @@ Objective-C retaining behavior attributes
In Objective-C, functions and methods are generally assumed to follow the
`Cocoa Memory Management
-<http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html>`_
+<https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html>`_
conventions for ownership of object arguments and
return values. However, there are exceptions, and so Clang provides attributes
to allow these exceptions to be documented. This are used by ARC and the
@@ -1777,7 +1791,7 @@ the arguments. Both arguments and the result have the bitwidth specified
by the name of the builtin.
``__builtin_rotateright``
-_------------------------
+-------------------------
* ``__builtin_rotateright8``
* ``__builtin_rotateright16``
@@ -2218,7 +2232,7 @@ C++ Coroutines support builtins
guaranteed.
Clang provides experimental builtins to support C++ Coroutines as defined by
-http://wg21.link/P0057. The following four are intended to be used by the
+https://wg21.link/P0057. The following four are intended to be used by the
standard library to implement `std::experimental::coroutine_handle` type.
**Syntax**:
@@ -2296,10 +2310,10 @@ Clang supports GCC's ``gnu`` attribute namespace. All GCC attributes which
are accepted with the ``__attribute__((foo))`` syntax are also accepted as
``[[gnu::foo]]``. This only extends to attributes which are specified by GCC
(see the list of `GCC function attributes
-<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_, `GCC variable
-attributes <http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html>`_, and
+<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_, `GCC variable
+attributes <https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html>`_, and
`GCC type attributes
-<http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html>`_). As with the GCC
+<https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html>`_). As with the GCC
implementation, these attributes must appertain to the *declarator-id* in a
declaration, which means they must go either at the start of the declaration or
immediately after the name being declared.
@@ -2362,6 +2376,103 @@ Which compiles to (on X86-32):
movl %gs:(%eax), %eax
ret
+PowerPC Language Extensions
+------------------------------
+
+Set the Floating Point Rounding Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+PowerPC64/PowerPC64le supports the builtin function ``__builtin_setrnd`` to set
+the floating point rounding mode. This function will use the least significant
+two bits of integer argument to set the floating point rounding mode.
+
+.. code-block:: c++
+
+ double __builtin_setrnd(int mode);
+
+The effective values for mode are:
+
+ - 0 - round to nearest
+ - 1 - round to zero
+ - 2 - round to +infinity
+ - 3 - round to -infinity
+
+Note that the mode argument will modulo 4, so if the int argument is greater
+than 3, it will only use the least significant two bits of the mode.
+Namely, ``__builtin_setrnd(102))`` is equal to ``__builtin_setrnd(2)``.
+
+PowerPC Language Extensions
+------------------------------
+
+Set the Floating Point Rounding Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+PowerPC64/PowerPC64le supports the builtin function ``__builtin_setrnd`` to set
+the floating point rounding mode. This function will use the least significant
+two bits of integer argument to set the floating point rounding mode.
+
+.. code-block:: c++
+
+ double __builtin_setrnd(int mode);
+
+The effective values for mode are:
+
+ - 0 - round to nearest
+ - 1 - round to zero
+ - 2 - round to +infinity
+ - 3 - round to -infinity
+
+Note that the mode argument will modulo 4, so if the integer argument is greater
+than 3, it will only use the least significant two bits of the mode.
+Namely, ``__builtin_setrnd(102))`` is equal to ``__builtin_setrnd(2)``.
+
+PowerPC Language Extensions
+------------------------------
+
+Set the Floating Point Rounding Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+PowerPC64/PowerPC64le supports the builtin function ``__builtin_setrnd`` to set
+the floating point rounding mode. This function will use the least significant
+two bits of integer argument to set the floating point rounding mode.
+
+.. code-block:: c++
+
+ double __builtin_setrnd(int mode);
+
+The effective values for mode are:
+
+ - 0 - round to nearest
+ - 1 - round to zero
+ - 2 - round to +infinity
+ - 3 - round to -infinity
+
+Note that the mode argument will modulo 4, so if the integer argument is greater
+than 3, it will only use the least significant two bits of the mode.
+Namely, ``__builtin_setrnd(102))`` is equal to ``__builtin_setrnd(2)``.
+
+PowerPC cache builtins
+^^^^^^^^^^^^^^^^^^^^^^
+
+The PowerPC architecture specifies instructions implementing cache operations.
+Clang provides builtins that give direct programmer access to these cache
+instructions.
+
+Currently the following builtins are implemented in clang:
+
+``__builtin_dcbf`` copies the contents of a modified block from the data cache
+to main memory and flushes the copy from the data cache.
+
+**Syntax**:
+
+.. code-block:: c
+
+ void __dcbf(const void* addr); /* Data Cache Block Flush */
+
+**Example of Use**:
+
+.. code-block:: c
+
+ int a = 1;
+ __builtin_dcbf (&a);
+
Extensions for Static Analysis
==============================
@@ -2908,3 +3019,29 @@ Specifying Linker Options on ELF Targets
The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets.
The second parameter is the library name (without the traditional Unix prefix of
``lib``). This allows you to provide an implicit link of dependent libraries.
+
+Evaluating Object Size Dynamically
+==================================
+
+Clang supports the builtin ``__builtin_dynamic_object_size``, the semantics are
+the same as GCC's ``__builtin_object_size`` (which Clang also supports), but
+``__builtin_dynamic_object_size`` can evaluate the object's size at runtime.
+``__builtin_dynamic_object_size`` is meant to be used as a drop-in replacement
+for ``__builtin_object_size`` in libraries that support it.
+
+For instance, here is a program that ``__builtin_dynamic_object_size`` will make
+safer:
+
+.. code-block:: c
+
+ void copy_into_buffer(size_t size) {
+ char* buffer = malloc(size);
+ strlcpy(buffer, "some string", strlen("some string"));
+ // Previous line preprocesses to:
+ // __builtin___strlcpy_chk(buffer, "some string", strlen("some string"), __builtin_object_size(buffer, 0))
+ }
+
+Since the size of ``buffer`` can't be known at compile time, Clang will fold
+``__builtin_object_size(buffer, 0)`` into ``-1``. However, if this was written
+as ``__builtin_dynamic_object_size(buffer, 0)``, Clang will fold it into
+``size``, providing some extra runtime safety.
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
index 2af0a7c9e3..a053bd1bb5 100644
--- a/docs/LibASTMatchersReference.html
+++ b/docs/LibASTMatchersReference.html
@@ -645,6 +645,19 @@ nestedNameSpecifier()
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>&gt;</td><td class="name" onclick="toggle('ompDefaultClause0')"><a name="ompDefaultClause0Anchor">ompDefaultClause</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="ompDefaultClause0"><pre>Matches OpenMP ``default`` clause.
+
+Given
+
+ #pragma omp parallel default(none)
+ #pragma omp parallel default(shared)
+ #pragma omp parallel
+
+``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('qualType0')"><a name="qualType0Anchor">qualType</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="qualType0"><pre>Matches QualTypes in the clang AST.
</pre></td></tr>
@@ -788,6 +801,11 @@ Example matches 'a', L'a'
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('chooseExpr0')"><a name="chooseExpr0Anchor">chooseExpr</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ChooseExpr.html">ChooseExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="chooseExpr0"><pre>Matches GNU __builtin_choose_expr.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('compoundLiteralExpr0')"><a name="compoundLiteralExpr0Anchor">compoundLiteralExpr</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="compoundLiteralExpr0"><pre>Matches compound (i.e. non-scalar) literals
@@ -1370,6 +1388,20 @@ Example matches @try
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('ompExecutableDirective0')"><a name="ompExecutableDirective0Anchor">ompExecutableDirective</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="ompExecutableDirective0"><pre>Matches any ``#pragma omp`` executable directive.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel default(none)
+ #pragma omp taskyield
+
+``ompExecutableDirective()`` matches ``omp parallel``,
+``omp parallel default(none)`` and ``omp taskyield``.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('opaqueValueExpr0')"><a name="opaqueValueExpr0Anchor">opaqueValueExpr</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OpaqueValueExpr.html">OpaqueValueExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="opaqueValueExpr0"><pre>Matches opaque value expressions. They are used as helpers
to reference another expressions and can be met
@@ -2608,6 +2640,9 @@ Example matches y(x) but not y(42) or NS::y(x).
Example: matches the implicit cast around 0
(matcher = castExpr(hasCastKind(CK_NullToPointer)))
int *p = 0;
+
+If the matcher is use from clang-query, CastKind parameter
+should be passed as a quoted string. e.g., ofKind("CK_NullToPointer").
</pre></td></tr>
@@ -2738,7 +2773,7 @@ Decl has pointer identity in the AST.
Given
__attribute__((device)) void f() { ... }
decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
-f. If the matcher is use from clang-query, attr::Kind parameter should be
+f. If the matcher is used from clang-query, attr::Kind parameter should be
passed as a quoted string. e.g., hasAttr("attr::CUDADevice").
</pre></td></tr>
@@ -2792,6 +2827,29 @@ by the compiler (eg. implicit default/copy constructors).
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isInStdNamespace0')"><a name="isInStdNamespace0Anchor">isInStdNamespace</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isInStdNamespace0"><pre>Matches declarations in the namespace `std`, but not in nested namespaces.
+
+Given
+ class vector {};
+ namespace foo {
+ class vector {};
+ namespace std {
+ class vector {};
+ }
+ }
+ namespace std {
+ inline namespace __1 {
+ class vector {}; // #1
+ namespace experimental {
+ class vector {};
+ }
+ }
+ }
+cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isPrivate0')"><a name="isPrivate0Anchor">isPrivate</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isPrivate0"><pre>Matches private C++ declarations.
@@ -3420,6 +3478,66 @@ namespaceDecl(isInline()) will match n::m.
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isNoneKind0')"><a name="isNoneKind0Anchor">isNoneKind</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isNoneKind0"><pre>Matches if the OpenMP ``default`` clause has ``none`` kind specified.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel default(none)
+ #pragma omp parallel default(shared)
+
+``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isSharedKind0')"><a name="isSharedKind0Anchor">isSharedKind</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isSharedKind0"><pre>Matches if the OpenMP ``default`` clause has ``shared`` kind specified.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel default(none)
+ #pragma omp parallel default(shared)
+
+``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('isAllowedToContainClauseKind0')"><a name="isAllowedToContainClauseKind0Anchor">isAllowedToContainClauseKind</a></td><td>OpenMPClauseKind CKind</td></tr>
+<tr><td colspan="4" class="doc" id="isAllowedToContainClauseKind0"><pre>Matches if the OpenMP directive is allowed to contain the specified OpenMP
+clause kind.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel for
+ #pragma omp for
+
+`ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches
+``omp parallel`` and ``omp parallel for``.
+
+If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter
+should be passed as a quoted string. e.g.,
+``isAllowedToContainClauseKind("OMPC_default").``
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('isStandaloneDirective0')"><a name="isStandaloneDirective0Anchor">isStandaloneDirective</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isStandaloneDirective0"><pre>Matches standalone OpenMP directives,
+i.e., directives that can't have a structured block.
+
+Given
+
+ #pragma omp parallel
+ {}
+ #pragma omp taskyield
+
+``ompExecutableDirective(isStandaloneDirective()))`` matches
+``omp taskyield``.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('argumentCountIs2')"><a name="argumentCountIs2Anchor">argumentCountIs</a></td><td>unsigned N</td></tr>
<tr><td colspan="4" class="doc" id="argumentCountIs2"><pre>Checks that a call expression or a constructor call expression has
a specific number of arguments (including absent default arguments).
@@ -3472,11 +3590,24 @@ represent an error condition in the tree!
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('isClassMessage0')"><a name="isClassMessage0Anchor">isClassMessage</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isClassMessage0"><pre>Returns true when the Objective-C message is sent to a class.
+
+Example
+matcher = objcMessageExpr(isClassMessage())
+matches
+ [NSString stringWithFormat:@"format"];
+but not
+ NSString *x = @"hello";
+ [x containsString:@"h"];
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('isInstanceMessage0')"><a name="isInstanceMessage0Anchor">isInstanceMessage</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isInstanceMessage0"><pre>Returns true when the Objective-C message is sent to an instance.
Example
-matcher = objcMessagaeExpr(isInstanceMessage())
+matcher = objcMessageExpr(isInstanceMessage())
matches
NSString *x = @"hello";
[x containsString:@"h"];
@@ -3485,6 +3616,30 @@ but not
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMethodDecl.html">ObjCMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isClassMethod0')"><a name="isClassMethod0Anchor">isClassMethod</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isClassMethod0"><pre>Returns true when the Objective-C method declaration is a class method.
+
+Example
+matcher = objcMethodDecl(isClassMethod())
+matches
+ @interface I + (void)foo; @end
+but not
+ @interface I - (void)bar; @end
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMethodDecl.html">ObjCMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isInstanceMessage0')"><a name="isInstanceMessage0Anchor">isInstanceMethod</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isInstanceMethod0"><pre>Returns true when the Objective-C method declaration is an instance method.
+
+Example
+matcher = objcMethodDecl(isInstanceMethod())
+matches
+ @interface I - (void)bar; @end
+but not
+ @interface I + (void)foo; @end
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('matchesSelector0')"><a name="matchesSelector0Anchor">matchesSelector</a></td><td>std::string RegExp</td></tr>
<tr><td colspan="4" class="doc" id="matchesSelector0"><pre>Matches ObjC selectors whose name contains
a substring matched by the given RegExp.
@@ -3790,6 +3945,19 @@ Usable as: Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('isOMPStructuredBlock0')"><a name="isOMPStructuredBlock0Anchor">isOMPStructuredBlock</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isOMPStructuredBlock0"><pre>Matches the Stmt AST node that is marked as being the structured-block
+of an OpenMP executable directive.
+
+Given
+
+ #pragma omp parallel
+ {}
+
+``stmt(isOMPStructuredBlock()))`` matches ``{}``.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1StringLiteral.html">StringLiteral</a>&gt;</td><td class="name" onclick="toggle('hasSize1')"><a name="hasSize1Anchor">hasSize</a></td><td>unsigned N</td></tr>
<tr><td colspan="4" class="doc" id="hasSize1"><pre>Matches nodes that have the specified size.
@@ -3981,6 +4149,9 @@ Given
int s = sizeof(x) + alignof(x)
unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
matches sizeof(x)
+
+If the matcher is use from clang-query, UnaryExprOrTypeTrait parameter
+should be passed as a quoted string. e.g., ofKind("UETT_SizeOf").
</pre></td></tr>
@@ -4810,16 +4981,20 @@ with withInitializer matching (1)
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html">CXXDependentScopeMemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression2')"><a name="hasObjectExpression2Anchor">hasObjectExpression</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasObjectExpression2"><pre>Matches a member expression where the object expression is
-matched by a given matcher.
+<tr><td colspan="4" class="doc" id="hasObjectExpression2"><pre>Matches a member expression where the object expression is matched by a
+given matcher. Implicit object expressions are included; that is, it matches
+use of implicit `this`.
Given
- struct X { int m; };
- void f(X x) { x.m; m; }
-memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
- matches "x.m" and "m"
-with hasObjectExpression(...)
- matching "x" and the implicit object expression of "m" which has type X*.
+ struct X {
+ int m;
+ int f(X x) { x.m; return m; }
+ };
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
+ matches `x.m`, but not `m`; however,
+memberExpr(hasObjectExpression(hasType(pointsTo(
+ cxxRecordDecl(hasName("X"))))))
+ matches `m` (aka. `this-&gt;m`), but not `x.m`.
</pre></td></tr>
@@ -4857,16 +5032,39 @@ matches 'a' in
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('onImplicitObjectArgument0')"><a name="onImplicitObjectArgument0Anchor">onImplicitObjectArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="onImplicitObjectArgument0"><pre></pre></td></tr>
+<tr><td colspan="4" class="doc" id="onImplicitObjectArgument0"><pre>Matches on the implicit object argument of a member call expression. Unlike
+`on`, matches the argument directly without stripping away anything.
+
+Given
+ class Y { public: void m(); };
+ Y g();
+ class X : public Y { void g(); };
+ void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); }
+cxxMemberCallExpr(onImplicitObjectArgument(hasType(
+ cxxRecordDecl(hasName("Y")))))
+ matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`.
+cxxMemberCallExpr(on(callExpr()))
+ does not match `(g()).m()`, because the parens are not ignored.
+
+FIXME: Overload to allow directly matching types?
+</pre></td></tr>
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('on0')"><a name="on0Anchor">on</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="on0"><pre>Matches on the implicit object argument of a member call expression.
+<tr><td colspan="4" class="doc" id="on0"><pre>Matches on the implicit object argument of a member call expression, after
+stripping off any parentheses or implicit casts.
-Example matches y.x()
- (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))))
- class Y { public: void x(); };
- void z() { Y y; y.x(); }
+Given
+ class Y { public: void m(); };
+ Y g();
+ class X : public Y {};
+ void z(Y y, X x) { y.m(); (g()).m(); x.m(); }
+cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))
+ matches `y.m()` and `(g()).m()`.
+cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))))
+ matches `x.m()`.
+cxxMemberCallExpr(on(callExpr()))
+ matches `(g()).m()`.
FIXME: Overload to allow directly matching types?
</pre></td></tr>
@@ -4878,8 +5076,20 @@ FIXME: Overload to allow directly matching types?
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('thisPointerType0')"><a name="thisPointerType0Anchor">thisPointerType</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="thisPointerType0"><pre>Matches if the expression's type either matches the specified
-matcher, or is a pointer to a type that matches the InnerMatcher.
+<tr><td colspan="4" class="doc" id="thisPointerType0"><pre>Matches if the type of the expression's implicit object argument either
+matches the InnerMatcher, or is a pointer to a type that matches the
+InnerMatcher.
+
+Given
+ class Y { public: void m(); };
+ class X : public Y { void g(); };
+ void z() { Y y; y.m(); Y *p; p-&gt;m(); X x; x.m(); x.g(); }
+cxxMemberCallExpr(thisPointerType(hasDeclaration(
+ cxxRecordDecl(hasName("Y")))))
+ matches `y.m()`, `p-&gt;m()` and `x.m()`.
+cxxMemberCallExpr(thisPointerType(hasDeclaration(
+ cxxRecordDecl(hasName("X")))))
+ matches `x.g()`.
</pre></td></tr>
@@ -5984,16 +6194,20 @@ Usable as: Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Addr
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression0')"><a name="hasObjectExpression0Anchor">hasObjectExpression</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasObjectExpression0"><pre>Matches a member expression where the object expression is
-matched by a given matcher.
+<tr><td colspan="4" class="doc" id="hasObjectExpression0"><pre>Matches a member expression where the object expression is matched by a
+given matcher. Implicit object expressions are included; that is, it matches
+use of implicit `this`.
Given
- struct X { int m; };
- void f(X x) { x.m; m; }
-memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
- matches "x.m" and "m"
-with hasObjectExpression(...)
- matching "x" and the implicit object expression of "m" which has type X*.
+ struct X {
+ int m;
+ int f(X x) { x.m; return m; }
+ };
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
+ matches `x.m`, but not `m`; however,
+memberExpr(hasObjectExpression(hasType(pointsTo(
+ cxxRecordDecl(hasName("X"))))))
+ matches `m` (aka. `this-&gt;m`), but not `x.m`.
</pre></td></tr>
@@ -6101,6 +6315,36 @@ nestedNameSpecifier(specifiesType(
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('hasAnyClause0')"><a name="hasAnyClause0Anchor">hasAnyClause</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyClause0"><pre>Matches any clause in an OpenMP directive.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel default(none)
+
+``ompExecutableDirective(hasAnyClause(anything()))`` matches
+``omp parallel default(none)``.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('hasStructuredBlock0')"><a name="hasStructuredBlock0Anchor">hasStructuredBlock</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasStructuredBlock0"><pre>Matches the structured-block of the OpenMP executable directive
+
+Prerequisite: the executable directive must not be standalone directive.
+If it is, it will never match.
+
+Given
+
+ #pragma omp parallel
+ ;
+ #pragma omp parallel
+ {}
+
+``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;``
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('hasAnyArgument3')"><a name="hasAnyArgument3Anchor">hasAnyArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasAnyArgument3"><pre>Matches any argument of a call expression or a constructor call
expression, or an ObjC-message-send expression.
@@ -6805,16 +7049,20 @@ Example matches true (matcher = hasUnaryOperand(
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedMemberExpr.html">UnresolvedMemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression1')"><a name="hasObjectExpression1Anchor">hasObjectExpression</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasObjectExpression1"><pre>Matches a member expression where the object expression is
-matched by a given matcher.
+<tr><td colspan="4" class="doc" id="hasObjectExpression1"><pre>Matches a member expression where the object expression is matched by a
+given matcher. Implicit object expressions are included; that is, it matches
+use of implicit `this`.
Given
- struct X { int m; };
- void f(X x) { x.m; m; }
-memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
- matches "x.m" and "m"
-with hasObjectExpression(...)
- matching "x" and the implicit object expression of "m" which has type X*.
+ struct X {
+ int m;
+ int f(X x) { x.m; return m; }
+ };
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
+ matches `x.m`, but not `m`; however,
+memberExpr(hasObjectExpression(hasType(pointsTo(
+ cxxRecordDecl(hasName("X"))))))
+ matches `m` (aka. `this-&gt;m`), but not `x.m`.
</pre></td></tr>
diff --git a/docs/LibASTMatchersTutorial.rst b/docs/LibASTMatchersTutorial.rst
index 8b7ee7f98f..24659a5209 100644
--- a/docs/LibASTMatchersTutorial.rst
+++ b/docs/LibASTMatchersTutorial.rst
@@ -16,23 +16,16 @@ Step 0: Obtaining Clang
=======================
As Clang is part of the LLVM project, you'll need to download LLVM's
-source code first. Both Clang and LLVM are maintained as Subversion
-repositories, but we'll be accessing them through the git mirror. For
-further information, see the `getting started
-guide <https://llvm.org/docs/GettingStarted.html>`_.
+source code first. Both Clang and LLVM are in the same git repository,
+under different directories. For further information, see the `getting
+started guide <https://llvm.org/docs/GettingStarted.html>`_.
.. code-block:: console
- mkdir ~/clang-llvm && cd ~/clang-llvm
- git clone https://llvm.org/git/llvm.git
- cd llvm/tools
- git clone https://llvm.org/git/clang.git
- cd clang/tools
- git clone https://llvm.org/git/clang-tools-extra.git extra
+ cd ~/clang-llvm
+ git clone https://github.com/llvm/llvm-project.git
-Next you need to obtain the CMake build system and Ninja build tool. You
-may already have CMake installed, but current binary versions of CMake
-aren't built with Ninja support.
+Next you need to obtain the CMake build system and Ninja build tool.
.. code-block:: console
@@ -57,7 +50,7 @@ Okay. Now we'll build Clang!
cd ~/clang-llvm
mkdir build && cd build
- cmake -G Ninja ../llvm -DLLVM_BUILD_TESTS=ON # Enable tests; default is off.
+ cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS=clang -DLLVM_BUILD_TESTS=ON # Enable tests; default is off.
ninja
ninja check # Test LLVM only.
ninja clang-test # Test Clang only.
@@ -65,9 +58,7 @@ Okay. Now we'll build Clang!
And we're live.
-All of the tests should pass, though there is a (very) small chance that
-you can catch LLVM and Clang out of sync. Running ``'git svn rebase'``
-in both the llvm and clang directories should fix any problems.
+All of the tests should pass.
Finally, we want to set Clang as its own compiler.
diff --git a/docs/LibTooling.rst b/docs/LibTooling.rst
index 41110f5d31..2aaa508a13 100644
--- a/docs/LibTooling.rst
+++ b/docs/LibTooling.rst
@@ -187,8 +187,8 @@ Clang tools need their builtin headers and search for them the same way Clang
does. Thus, the default location to look for builtin headers is in a path
``$(dirname /path/to/tool)/../lib/clang/3.3/include`` relative to the tool
binary. This works out-of-the-box for tools running from llvm's toplevel
-binary directory after building clang-headers, or if the tool is running from
-the binary directory of a clang install next to the clang binary.
+binary directory after building clang-resource-headers, or if the tool is
+running from the binary directory of a clang install next to the clang binary.
Tips: if your tool fails to find ``stddef.h`` or similar headers, call the tool
with ``-v`` and look at the search paths it looks through.
@@ -196,6 +196,6 @@ with ``-v`` and look at the search paths it looks through.
Linking
^^^^^^^
-For a list of libraries to link, look at one of the tools' Makefiles (for
-example `clang-check/Makefile
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-check/Makefile?view=markup>`_).
+For a list of libraries to link, look at one of the tools' CMake files (for
+example `clang-check/CMakeList.txt
+<https://github.com/llvm/llvm-project/blob/master/clang/tools/clang-check/CMakeLists.txt>`_).
diff --git a/docs/MSVCCompatibility.rst b/docs/MSVCCompatibility.rst
index cd2acae970..b2486052ab 100644
--- a/docs/MSVCCompatibility.rst
+++ b/docs/MSVCCompatibility.rst
@@ -68,8 +68,8 @@ The status of major ABI-impacting C++ features:
base class`_. Clang does not yet support this.
.. _#pragma pointers_to_members:
- http://msdn.microsoft.com/en-us/library/83cch5a6.aspx
-.. _/vm: http://msdn.microsoft.com/en-us/library/yad46a6z.aspx
+ https://msdn.microsoft.com/en-us/library/83cch5a6.aspx
+.. _/vm: https://msdn.microsoft.com/en-us/library/yad46a6z.aspx
.. _pointer to a member of a virtual base class: https://llvm.org/PR15713
* Debug info: :good:`Mostly complete`. Clang emits relatively complete CodeView
diff --git a/docs/OpenMPSupport.rst b/docs/OpenMPSupport.rst
index 04a9648ca2..a8bfddce63 100644
--- a/docs/OpenMPSupport.rst
+++ b/docs/OpenMPSupport.rst
@@ -17,60 +17,50 @@
OpenMP Support
==================
-Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64,
-PPC64[LE] and has `basic support for Cuda devices`_.
-
-Standalone directives
-=====================
-
-* #pragma omp [for] simd: :good:`Complete`.
-
-* #pragma omp declare simd: :partial:`Partial`. We support parsing/semantic
- analysis + generation of special attributes for X86 target, but still
- missing the LLVM pass for vectorization.
-
-* #pragma omp taskloop [simd]: :good:`Complete`.
-
-* #pragma omp target [enter|exit] data: :good:`Complete`.
-
-* #pragma omp target update: :good:`Complete`.
-
-* #pragma omp target: :good:`Complete`.
+Clang supports the following OpenMP 5.0 features
-* #pragma omp declare target: :good:`Complete`.
+* The `reduction`-based clauses in the `task` and `target`-based directives.
-* #pragma omp teams: :good:`Complete`.
+* Support relational-op != (not-equal) as one of the canonical forms of random
+ access iterator.
-* #pragma omp distribute [simd]: :good:`Complete`.
+* Support for mapping of the lambdas in target regions.
-* #pragma omp distribute parallel for [simd]: :good:`Complete`.
+* Parsing/sema analysis for the requires directive.
-Combined directives
-===================
+* Nested declare target directives.
-* #pragma omp parallel for simd: :good:`Complete`.
+* Make the `this` pointer implicitly mapped as `map(this[:1])`.
-* #pragma omp target parallel: :good:`Complete`.
+* The `close` *map-type-modifier*.
-* #pragma omp target parallel for [simd]: :good:`Complete`.
-
-* #pragma omp target simd: :good:`Complete`.
-
-* #pragma omp target teams: :good:`Complete`.
-
-* #pragma omp teams distribute [simd]: :good:`Complete`.
-
-* #pragma omp target teams distribute [simd]: :good:`Complete`.
-
-* #pragma omp teams distribute parallel for [simd]: :good:`Complete`.
-
-* #pragma omp target teams distribute parallel for [simd]: :good:`Complete`.
+Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64,
+PPC64[LE] and has `basic support for Cuda devices`_.
-Clang does not support any constructs/updates from OpenMP 5.0 except
-for `reduction`-based clauses in the `task` and `target`-based directives.
+* #pragma omp declare simd: :partial:`Partial`. We support parsing/semantic
+ analysis + generation of special attributes for X86 target, but still
+ missing the LLVM pass for vectorization.
In addition, the LLVM OpenMP runtime `libomp` supports the OpenMP Tools
-Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and mac OS.
+Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and macOS.
+
+General improvements
+--------------------
+- New collapse clause scheme to avoid expensive remainder operations.
+ Compute loop index variables after collapsing a loop nest via the
+ collapse clause by replacing the expensive remainder operation with
+ multiplications and additions.
+
+- The default schedules for the `distribute` and `for` constructs in a
+ parallel region and in SPMD mode have changed to ensure coalesced
+ accesses. For the `distribute` construct, a static schedule is used
+ with a chunk size equal to the number of threads per team (default
+ value of threads or as specified by the `thread_limit` clause if
+ present). For the `for` construct, the schedule is static with chunk
+ size of one.
+
+- Simplified SPMD code generation for `distribute parallel for` when
+ the new default schedules are applicable.
.. _basic support for Cuda devices:
@@ -111,7 +101,7 @@ between the threads in the parallel regions.
Collapsed loop nest counter
---------------------------
-When using the collapse clause on a loop nest the default behaviour is to
+When using the collapse clause on a loop nest the default behavior is to
automatically extend the representation of the loop counter to 64 bits for
the cases where the sizes of the collapsed loops are not known at compile
time. To prevent this conservative choice and use at most 32 bits,
@@ -134,5 +124,8 @@ Features not supported or with limited support for Cuda devices
- Automatic translation of math functions in target regions to device-specific
math functions is not implemented yet.
-- Debug information for OpenMP target regions is not supported yet.
+- Debug information for OpenMP target regions is supported, but sometimes it may
+ be required to manually specify the address class of the inspected variables.
+ In some cases the local variables are actually allocated in the global memory,
+ but the debug info may be not aware of it.
diff --git a/docs/PCHInternals.rst b/docs/PCHInternals.rst
index 109260da90..079fba1671 100644
--- a/docs/PCHInternals.rst
+++ b/docs/PCHInternals.rst
@@ -332,7 +332,7 @@ expression is stored as a separate record (which keeps most records to a fixed
size). Within the AST file, the subexpressions of an expression are stored, in
reverse order, prior to the expression that owns those expression, using a form
of `Reverse Polish Notation
-<http://en.wikipedia.org/wiki/Reverse_Polish_notation>`_. For example, an
+<https://en.wikipedia.org/wiki/Reverse_Polish_notation>`_. For example, an
expression ``3 - 4 + 5`` would be represented as follows:
+-----------------------+
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index b6a405dbc7..1f09655027 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,5 +1,5 @@
=======================================
-Clang 8.0.0 (In-Progress) Release Notes
+Clang 9.0.0 (In-Progress) Release Notes
=======================================
.. contents::
@@ -10,7 +10,7 @@ Written by the `LLVM Team <https://llvm.org/>`_
.. warning::
- These are in-progress notes for the upcoming Clang 8 release.
+ These are in-progress notes for the upcoming Clang 9 release.
Release notes for previous releases can be found on
`the Download Page <https://releases.llvm.org/download.html>`_.
@@ -18,7 +18,7 @@ Introduction
============
This document contains the release notes for the Clang C/C++/Objective-C
-frontend, part of the LLVM Compiler Infrastructure, release 8.0.0. Here we
+frontend, part of the LLVM Compiler Infrastructure, release 9.0.0. Here we
describe the status of Clang in some detail, including major
improvements from the previous release and new feature work. For the
general LLVM release notes, see `the LLVM
@@ -35,7 +35,7 @@ main Clang web page, this document applies to the *next* release, not
the current one. To see the release notes for a specific release, please
see the `releases page <https://llvm.org/releases/>`_.
-What's New in Clang 8.0.0?
+What's New in Clang 9.0.0?
==========================
Some of the major new features and improvements to Clang are listed
@@ -46,96 +46,22 @@ sections with improvements to Clang's support for those languages.
Major New Features
------------------
-- Clang supports use of a profile remapping file, which permits
- profile data captured for one version of a program to be applied
- when building another version where symbols have changed (for
- example, due to renaming a class or namespace).
- See the :doc:`UsersManual` for details.
+- ...
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-- ``-Wextra-semi-stmt`` is a new diagnostic that diagnoses extra semicolons,
- much like ``-Wextra-semi``. This new diagnostic diagnoses all *unnecessary*
- null statements (expression statements without an expression), unless: the
- semicolon directly follows a macro that was expanded to nothing or if the
- semicolon is within the macro itself. This applies to macros defined in system
- headers as well as user-defined macros.
-
- .. code-block:: c++
-
- #define MACRO(x) int x;
- #define NULLMACRO(varname)
-
- void test() {
- ; // <- warning: ';' with no preceding expression is a null statement
-
- while (true)
- ; // OK, it is needed.
-
- switch (my_enum) {
- case E1:
- // stuff
- break;
- case E2:
- ; // OK, it is needed.
- }
-
- MACRO(v0;) // Extra semicolon, but within macro, so ignored.
-
- MACRO(v1); // <- warning: ';' with no preceding expression is a null statement
-
- NULLMACRO(v2); // ignored, NULLMACRO expanded to nothing.
- }
-
-- ``-Wempty-init-stmt`` is a new diagnostic that diagnoses empty init-statements
- of ``if``, ``switch``, ``range-based for``, unless: the semicolon directly
- follows a macro that was expanded to nothing or if the semicolon is within the
- macro itself (both macros from system headers, and normal macros). This
- diagnostic is in the ``-Wextra-semi-stmt`` group and is enabled in
- ``-Wextra``.
-
- .. code-block:: c++
-
- void test() {
- if(; // <- warning: init-statement of 'if' is a null statement
- true)
- ;
-
- switch (; // <- warning: init-statement of 'switch' is a null statement
- x) {
- ...
- }
-
- for (; // <- warning: init-statement of 'range-based for' is a null statement
- int y : S())
- ;
- }
-
+- ...
Non-comprehensive list of changes in this release
-------------------------------------------------
-- The experimental feature Pretokenized Headers (PTH) was removed in its
- entirely from Clang. The feature did not properly work with about 1/3 of the
- possible tokens available and was unmaintained.
+- ...
-- The internals of libc++ include directory detection on MacOS have changed.
- Instead of running a search based on the ``-resource-dir`` flag, the search
- is now based on the path of the compiler in the filesystem. The default
- behaviour should not change. However, if you override ``-resource-dir``
- manually and rely on the old behaviour you will need to add appropriate
- compiler flags for finding the corresponding libc++ include directory.
New Compiler Flags
------------------
-- ``-fprofile-filter-files=[regexes]`` and ``-fprofile-exclude-files=[regexes]``.
-
- Clang has now options to filter or exclude some files when
- instrumenting for gcov-based profiling.
- See the :doc:`UsersManual` for details.
-
- ...
Deprecated Compiler Flags
@@ -149,17 +75,14 @@ future versions of Clang.
Modified Compiler Flags
-----------------------
-- As of clang 8, `alignof` and `_Alignof` return the ABI alignment of a type,
- as opposed to the preferred alignment. `__alignof` still returns the
- preferred alignment. `-fclang-abi-compat=7` (and previous) will make
- `alignof` and `_Alignof` return preferred alignment again.
+- `clang -dumpversion` now returns the version of Clang itself.
+- ...
New Pragmas in Clang
--------------------
-- Clang now supports adding multiple `#pragma clang attribute` attributes into
- a scope of pushed attributes.
+- ...
Attribute Changes in Clang
--------------------------
@@ -169,16 +92,6 @@ Attribute Changes in Clang
Windows Support
---------------
-- clang-cl now supports the use of the precompiled header options /Yc and /Yu
- without the filename argument. When these options are used without the
- filename, a `#pragma hdrstop` inside the source marks the end of the
- precompiled code.
-
-- clang-cl has a new command-line option, ``/Zc:dllexportInlines-``, similar to
- ``-fvisibility-inlines-hidden`` on non-Windows, that makes class-level
- `dllexport` and `dllimport` attributes not apply to inline member functions.
- This can significantly reduce compile and link times. See the `User's Manual
- <UsersManual.html#the-zc-dllexportinlines-option>`_ for more info.
- ...
@@ -217,52 +130,38 @@ OpenCL C Language Changes in Clang
ABI Changes in Clang
--------------------
-- `_Alignof` and `alignof` now return the ABI alignment of a type, as opposed
- to the preferred alignment.
-
- - This is more in keeping with the language of the standards, as well as
- being compatible with gcc
- - `__alignof` and `__alignof__` still return the preferred alignment of
- a type
- - This shouldn't break any ABI except for things that explicitly ask for
- `alignas(alignof(T))`.
- - If you have interfaces that break with this change, you may wish to switch
- to `alignas(__alignof(T))`, instead of using the `-fclang-abi-compat`
- switch.
+- ...
OpenMP Support in Clang
-----------------------------------
-
-- Support relational-op != (not-equal) as one of the canonical forms of random
- access iterator.
-
-- Added support for mapping of the lambdas in target regions.
-
-- Added parsing/sema analysis for OpenMP 5.0 requires directive.
-
-- Various bugfixes and improvements.
-
-New features supported for Cuda devices:
-
-- Added support for the reductions across the teams.
-
-- Extended number of constructs that can be executed in SPMD mode.
-
-- Fixed support for lastprivate/reduction variables in SPMD constructs.
+-----------------------
-- General performance improvement.
+- Added emission of the debug information for NVPTX target devices.
CUDA Support in Clang
---------------------
+- Added emission of the debug information for the device code.
Internal API Changes
--------------------
-These are major API changes that have happened since the 7.0.0 release of
+These are major API changes that have happened since the 8.0.0 release of
Clang. If upgrading an external codebase that uses Clang as a library,
this section should help get you past the largest hurdles of upgrading.
+Build System Changes
+--------------------
+
+These are major changes to the build system that have happened since the 8.0.0
+release of Clang. Users of the build system should adjust accordingly.
+
+- In 8.0.0 and below, the install-clang-headers target would install clang's
+ resource directory headers. This installation is now performed by the
+ install-clang-resource-headers target. Users of the old install-clang-headers
+ target should switch to the new install-clang-resource-headers target. The
+ install-clang-headers target now installs clang's API headers (corresponding
+ to its libraries), which is consistent with the install-llvm-headers target.
+
- ...
AST Matchers
@@ -273,19 +172,26 @@ AST Matchers
clang-format
------------
-
-- ...
+- Add language support for clang-formatting C# files
+- Add Microsoft coding style to encapsulate default C# formatting style
+- Added new option `PPDIS_BeforeHash` (in configuration: `BeforeHash`) to
+ `IndentPPDirectives` which indents preprocessor directives before the hash.
libclang
--------
-...
+- When `CINDEXTEST_INCLUDE_ATTRIBUTED_TYPES` is not provided when making a
+ CXType, the equivalent type of the AttributedType is returned instead of the
+ modified type if the user does not want attribute sugar. The equivalent type
+ represents the minimally-desugared type which the AttributedType is
+ canonically equivalent to.
Static Analyzer
---------------
-- ...
+- The UninitializedObject checker is now considered as stable.
+ (moved from the 'alpha.cplusplus' to the 'optin.cplusplus' package)
...
@@ -294,75 +200,7 @@ Static Analyzer
Undefined Behavior Sanitizer (UBSan)
------------------------------------
-* The Implicit Conversion Sanitizer (``-fsanitize=implicit-conversion``) group
- was extended. One more type of issues is caught - implicit integer sign change.
- (``-fsanitize=implicit-integer-sign-change``).
- This makes the Implicit Conversion Sanitizer feature-complete,
- with only missing piece being bitfield handling.
- While there is a ``-Wsign-conversion`` diagnostic group that catches this kind
- of issues, it is both noisy, and does not catch **all** the cases.
-
- .. code-block:: c++
-
- bool consume(unsigned int val);
-
- void test(int val) {
- (void)consume(val); // If the value was negative, it is now large positive.
- (void)consume((unsigned int)val); // OK, the conversion is explicit.
- }
-
- Like some other ``-fsanitize=integer`` checks, these issues are **not**
- undefined behaviour. But they are not *always* intentional, and are somewhat
- hard to track down. This group is **not** enabled by ``-fsanitize=undefined``,
- but the ``-fsanitize=implicit-integer-sign-change`` check
- is enabled by ``-fsanitize=integer``.
- (as is ``-fsanitize=implicit-integer-truncation`` check)
-
-* The Implicit Conversion Sanitizer (``-fsanitize=implicit-conversion``) has
- learned to sanitize compound assignment operators.
-
-* ``alignment`` check has learned to sanitize the assume_aligned-like attributes:
-
- .. code-block:: c++
-
- typedef char **__attribute__((align_value(1024))) aligned_char;
- struct ac_struct {
- aligned_char a;
- };
- char **load_from_ac_struct(struct ac_struct *x) {
- return x->a; // <- check that loaded 'a' is aligned
- }
-
- char **passthrough(__attribute__((align_value(1024))) char **x) {
- return x; // <- check the pointer passed as function argument
- }
-
- char **__attribute__((alloc_align(2)))
- alloc_align(int size, unsigned long alignment);
-
- char **caller(int size) {
- return alloc_align(size, 1024); // <- check returned pointer
- }
-
- char **__attribute__((assume_aligned(1024))) get_ptr();
-
- char **caller2() {
- return get_ptr(); // <- check returned pointer
- }
-
- void *caller3(char **x) {
- return __builtin_assume_aligned(x, 1024); // <- check returned pointer
- }
-
- void *caller4(char **x, unsigned long offset) {
- return __builtin_assume_aligned(x, 1024, offset); // <- check returned pointer accounting for the offest
- }
-
- void process(char *data, int width) {
- #pragma omp for simd aligned(data : 1024) // <- aligned clause will be checked.
- for (int x = 0; x < width; x++)
- data[x] *= data[x];
- }
+- ...
Core Analysis Improvements
==========================
diff --git a/docs/SafeStack.rst b/docs/SafeStack.rst
index b046aa6168..c1e09da935 100644
--- a/docs/SafeStack.rst
+++ b/docs/SafeStack.rst
@@ -18,14 +18,14 @@ buffer overflows on the unsafe stack cannot be used to overwrite anything
on the safe stack.
SafeStack is a part of the `Code-Pointer Integrity (CPI) Project
-<http://dslab.epfl.ch/proj/cpi/>`_.
+<https://dslab.epfl.ch/proj/cpi/>`_.
Performance
-----------
The performance overhead of the SafeStack instrumentation is less than 0.1% on
average across a variety of benchmarks (see the `Code-Pointer Integrity
-<http://dslab.epfl.ch/pubs/cpi.pdf>`__ paper for details). This is mainly
+<https://dslab.epfl.ch/pubs/cpi.pdf>`__ paper for details). This is mainly
because most small functions do not have any variables that require the unsafe
stack and, hence, do not need unsafe stack frames to be created. The cost of
creating unsafe stack frames for large functions is amortized by the cost of
@@ -84,9 +84,9 @@ Known security limitations
A complete protection against control-flow hijack attacks requires combining
SafeStack with another mechanism that enforces the integrity of code pointers
that are stored on the heap or the unsafe stack, such as `CPI
-<http://dslab.epfl.ch/proj/cpi/>`_, or a forward-edge control flow integrity
+<https://dslab.epfl.ch/proj/cpi/>`_, or a forward-edge control flow integrity
mechanism that enforces correct calling conventions at indirect call sites,
-such as `IFCC <http://research.google.com/pubs/archive/42808.pdf>`_ with arity
+such as `IFCC <https://research.google.com/pubs/archive/42808.pdf>`_ with arity
checks. Clang has control-flow integrity protection scheme for :doc:`C++ virtual
calls <ControlFlowIntegrity>`, but not non-virtual indirect calls. With
SafeStack alone, an attacker can overwrite a function pointer on the heap or
@@ -106,7 +106,7 @@ prevented by adjusting such functions to either encrypt the stack pointer when
storing it in the heap (as already done e.g., by ``setjmp``/``longjmp``
implementation in glibc), or store it in a safe region instead.
-The `CPI paper <http://dslab.epfl.ch/pubs/cpi.pdf>`_ describes two alternative,
+The `CPI paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ describes two alternative,
stronger safe stack protection mechanisms, that rely on software fault
isolation, or hardware segmentation (as available on x86-32 and some x86-64
CPUs).
@@ -186,14 +186,14 @@ Deprecated: This builtin function is an alias for
Design
======
-Please refer to the `Code-Pointer Integrity <http://dslab.epfl.ch/proj/cpi/>`__
+Please refer to the `Code-Pointer Integrity <https://dslab.epfl.ch/proj/cpi/>`__
project page for more information about the design of the SafeStack and its
related technologies.
setjmp and exception handling
-----------------------------
-The `OSDI'14 paper <http://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that
+The `OSDI'14 paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that
on Linux the instrumentation pass finds calls to setjmp or functions that
may throw an exception, and inserts required instrumentation at their call
sites. Specifically, the instrumentation pass saves the shadow stack pointer
@@ -204,7 +204,7 @@ in the function ``SafeStack::createStackRestorePoints``.
Publications
------------
-`Code-Pointer Integrity <http://dslab.epfl.ch/pubs/cpi.pdf>`__.
+`Code-Pointer Integrity <https://dslab.epfl.ch/pubs/cpi.pdf>`__.
Volodymyr Kuznetsov, Laszlo Szekeres, Mathias Payer, George Candea, R. Sekar, Dawn Song.
USENIX Symposium on Operating Systems Design and Implementation
(`OSDI <https://www.usenix.org/conference/osdi14>`_), Broomfield, CO, October 2014
diff --git a/docs/SanitizerCoverage.rst b/docs/SanitizerCoverage.rst
index f3f13c8317..c7cd853dd6 100644
--- a/docs/SanitizerCoverage.rst
+++ b/docs/SanitizerCoverage.rst
@@ -144,6 +144,11 @@ PC-Table
**Experimental, may change or disappear in future**
+**Note:** this instrumentation might be incompatible with dead code stripping
+(``-Wl,-gc-sections``) for linkers other than LLD, thus resulting in a
+significant binary size overhead. For more information, see
+`Bug 34636 <https://bugs.llvm.org/show_bug.cgi?id=34636>`_.
+
With ``-fsanitize-coverage=pc-table`` the compiler will create a table of
instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters`` or
``-fsanitize-coverage=trace-pc-guard``.
@@ -222,9 +227,9 @@ It contains 3 basic blocks, let's name them A, B, C:
If blocks A, B, and C are all covered we know for certain that the edges A=>B
and B=>C were executed, but we still don't know if the edge A=>C was executed.
Such edges of control flow graph are called
-`critical <http://en.wikipedia.org/wiki/Control_flow_graph#Special_edges>`_. The
-edge-level coverage simply splits all critical
-edges by introducing new dummy blocks and then instruments those blocks:
+`critical <https://en.wikipedia.org/wiki/Control_flow_graph#Special_edges>`_.
+The edge-level coverage simply splits all critical edges by introducing new
+dummy blocks and then instruments those blocks:
.. code-block:: none
@@ -248,6 +253,9 @@ and with ``-fsanitize-coverage=trace-gep`` --
the `LLVM GEP instructions <https://llvm.org/docs/GetElementPtr.html>`_
(to capture array indices).
+Unless ``no-prune`` option is provided, some of the comparison instructions
+will not be instrumented.
+
.. code-block:: c++
// Called before a comparison instruction.
diff --git a/docs/ShadowCallStack.rst b/docs/ShadowCallStack.rst
index da609dcd9d..b1ab4c6e8b 100644
--- a/docs/ShadowCallStack.rst
+++ b/docs/ShadowCallStack.rst
@@ -8,28 +8,43 @@ ShadowCallStack
Introduction
============
-ShadowCallStack is an **experimental** instrumentation pass, currently only
-implemented for x86_64 and aarch64, that protects programs against return
-address overwrites (e.g. stack buffer overflows.) It works by saving a
-function's return address to a separately allocated 'shadow call stack'
-in the function prolog and checking the return address on the stack against
-the shadow call stack in the function epilog.
+ShadowCallStack is an instrumentation pass, currently only implemented for
+aarch64, that protects programs against return address overwrites
+(e.g. stack buffer overflows.) It works by saving a function's return address
+to a separately allocated 'shadow call stack' in the function prolog in
+non-leaf functions and loading the return address from the shadow call stack
+in the function epilog. The return address is also stored on the regular stack
+for compatibility with unwinders, but is otherwise unused.
+
+The aarch64 implementation is considered production ready, and
+an `implementation of the runtime`_ has been added to Android's libc
+(bionic). An x86_64 implementation was evaluated using Chromium and was found
+to have critical performance and security deficiencies--it was removed in
+LLVM 9.0. Details on the x86_64 implementation can be found in the
+`Clang 7.0.1 documentation`_.
+
+.. _`implementation of the runtime`: https://android.googlesource.com/platform/bionic/+/808d176e7e0dd727c7f929622ec017f6e065c582/libc/bionic/pthread_create.cpp#128
+.. _`Clang 7.0.1 documentation`: https://releases.llvm.org/7.0.1/tools/clang/docs/ShadowCallStack.html
Comparison
----------
-To optimize for memory consumption and cache locality, the shadow call stack
-stores an index followed by an array of return addresses. This is in contrast
-to other schemes, like :doc:`SafeStack`, that mirror the entire stack and
-trade-off consuming more memory for shorter function prologs and epilogs with
-fewer memory accesses. Similarly, `Return Flow Guard`_ consumes more memory with
-shorter function prologs and epilogs than ShadowCallStack but suffers from the
-same race conditions (see `Security`_). Intel `Control-flow Enforcement Technology`_
-(CET) is a proposed hardware extension that would add native support to
-use a shadow stack to store/check return addresses at call/return time. It
-would not suffer from race conditions at calls and returns and not incur the
-overhead of function instrumentation, but it does require operating system
-support.
+To optimize for memory consumption and cache locality, the shadow call
+stack stores only an array of return addresses. This is in contrast to other
+schemes, like :doc:`SafeStack`, that mirror the entire stack and trade-off
+consuming more memory for shorter function prologs and epilogs with fewer
+memory accesses.
+
+`Return Flow Guard`_ is a pure software implementation of shadow call stacks
+on x86_64. Like the previous implementation of ShadowCallStack on x86_64, it is
+inherently racy due to the architecture's use of the stack for calls and
+returns.
+
+Intel `Control-flow Enforcement Technology`_ (CET) is a proposed hardware
+extension that would add native support to use a shadow stack to store/check
+return addresses at call/return time. Being a hardware implementation, it
+would not suffer from race conditions and would not incur the overhead of
+function instrumentation, but it does require operating system support.
.. _`Return Flow Guard`: https://xlab.tencent.com/en/2016/11/02/return-flow-guard/
.. _`Control-flow Enforcement Technology`: https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
@@ -37,57 +52,96 @@ support.
Compatibility
-------------
-ShadowCallStack currently only supports x86_64 and aarch64. A runtime is not
-currently provided in compiler-rt so one must be provided by the compiled
-application.
-
-On aarch64, the instrumentation makes use of the platform register ``x18``.
-On some platforms, ``x18`` is reserved, and on others, it is designated as
-a scratch register. This generally means that any code that may run on the
-same thread as code compiled with ShadowCallStack must either target one
-of the platforms whose ABI reserves ``x18`` (currently Darwin, Fuchsia and
-Windows) or be compiled with the flag ``-ffixed-x18``.
+A runtime is not provided in compiler-rt so one must be provided by the
+compiled application or the operating system. Integrating the runtime into
+the operating system should be preferred since otherwise all thread creation
+and destruction would need to be intercepted by the application.
+
+The instrumentation makes use of the platform register ``x18``. On some
+platforms, ``x18`` is reserved, and on others, it is designated as a scratch
+register. This generally means that any code that may run on the same thread
+as code compiled with ShadowCallStack must either target one of the platforms
+whose ABI reserves ``x18`` (currently Android, Darwin, Fuchsia and Windows)
+or be compiled with the flag ``-ffixed-x18``. If absolutely necessary, code
+compiled without ``-ffixed-x18`` may be run on the same thread as code that
+uses ShadowCallStack by saving the register value temporarily on the stack
+(`example in Android`_) but this should be done with care since it risks
+leaking the shadow call stack address.
+
+.. _`example in Android`: https://android-review.googlesource.com/c/platform/frameworks/base/+/803717
+
+Because of the use of register ``x18``, the ShadowCallStack feature is
+incompatible with any other feature that may use ``x18``. However, there
+is no inherent reason why ShadowCallStack needs to use register ``x18``
+specifically; in principle, a platform could choose to reserve and use another
+register for ShadowCallStack, but this would be incompatible with the AAPCS64.
+
+Special unwind information is required on functions that are compiled
+with ShadowCallStack and that may be unwound, i.e. functions compiled with
+``-fexceptions`` (which is the default in C++). Some unwinders (such as the
+libgcc 4.9 unwinder) do not understand this unwind info and will segfault
+when encountering it. LLVM libunwind processes this unwind info correctly,
+however. This means that if exceptions are used together with ShadowCallStack,
+the program must use a compatible unwinder.
Security
========
ShadowCallStack is intended to be a stronger alternative to
``-fstack-protector``. It protects from non-linear overflows and arbitrary
-memory writes to the return address slot; however, similarly to
-``-fstack-protector`` this protection suffers from race conditions because of
-the call-return semantics on x86_64. There is a short race between the call
-instruction and the first instruction in the function that reads the return
-address where an attacker could overwrite the return address and bypass
-ShadowCallStack. Similarly, there is a time-of-check-to-time-of-use race in the
-function epilog where an attacker could overwrite the return address after it
-has been checked and before it has been returned to. Modifying the call-return
-semantics to fix this on x86_64 would incur an unacceptable performance overhead
-due to return branch prediction.
-
-The instrumentation makes use of the ``gs`` segment register on x86_64,
-or the ``x18`` register on aarch64, to reference the shadow call stack
-meaning that references to the shadow call stack do not have to be stored in
-memory. This makes it possible to implement a runtime that avoids exposing
-the address of the shadow call stack to attackers that can read arbitrary
-memory. However, attackers could still try to exploit side channels exposed
-by the operating system `[1]`_ `[2]`_ or processor `[3]`_ to discover the
-address of the shadow call stack.
+memory writes to the return address slot.
+
+The instrumentation makes use of the ``x18`` register to reference the shadow
+call stack, meaning that references to the shadow call stack do not have
+to be stored in memory. This makes it possible to implement a runtime that
+avoids exposing the address of the shadow call stack to attackers that can
+read arbitrary memory. However, attackers could still try to exploit side
+channels exposed by the operating system `[1]`_ `[2]`_ or processor `[3]`_
+to discover the address of the shadow call stack.
.. _`[1]`: https://eyalitkin.wordpress.com/2017/09/01/cartography-lighting-up-the-shadows/
.. _`[2]`: https://www.blackhat.com/docs/eu-16/materials/eu-16-Goktas-Bypassing-Clangs-SafeStack.pdf
.. _`[3]`: https://www.vusec.net/projects/anc/
-On x86_64, leaf functions are optimized to store the return address in a
-free register and avoid writing to the shadow call stack if a register is
-available. Very short leaf functions are uninstrumented if their execution
-is judged to be shorter than the race condition window intrinsic to the
-instrumentation.
-
-On aarch64, the architecture's call and return instructions (``bl`` and
-``ret``) operate on a register rather than the stack, which means that
-leaf functions are generally protected from return address overwrites even
-without ShadowCallStack. It also means that ShadowCallStack on aarch64 is not
-vulnerable to the same types of time-of-check-to-time-of-use races as x86_64.
+Unless care is taken when allocating the shadow call stack, it may be
+possible for an attacker to guess its address using the addresses of
+other allocations. Therefore, the address should be chosen to make this
+difficult. One way to do this is to allocate a large guard region without
+read/write permissions, randomly select a small region within it to be
+used as the address of the shadow call stack and mark only that region as
+read/write. This also mitigates somewhat against processor side channels.
+The intent is that the Android runtime `will do this`_, but the platform will
+first need to be `changed`_ to avoid using ``setrlimit(RLIMIT_AS)`` to limit
+memory allocations in certain processes, as this also limits the number of
+guard regions that can be allocated.
+
+.. _`will do this`: https://android-review.googlesource.com/c/platform/bionic/+/891622
+.. _`changed`: https://android-review.googlesource.com/c/platform/frameworks/av/+/837745
+
+The runtime will need the address of the shadow call stack in order to
+deallocate it when destroying the thread. If the entire program is compiled
+with ``-ffixed-x18``, this is trivial: the address can be derived from the
+value stored in ``x18`` (e.g. by masking out the lower bits). If a guard
+region is used, the address of the start of the guard region could then be
+stored at the start of the shadow call stack itself. But if it is possible
+for code compiled without ``-ffixed-x18`` to run on a thread managed by the
+runtime, which is the case on Android for example, the address must be stored
+somewhere else instead. On Android we store the address of the start of the
+guard region in TLS and deallocate the entire guard region including the
+shadow call stack at thread exit. This is considered acceptable given that
+the address of the start of the guard region is already somewhat guessable.
+
+One way in which the address of the shadow call stack could leak is in the
+``jmp_buf`` data structure used by ``setjmp`` and ``longjmp``. The Android
+runtime `avoids this`_ by only storing the low bits of ``x18`` in the
+``jmp_buf``, which requires the address of the shadow call stack to be
+aligned to its size.
+
+.. _`avoids this`: https://android.googlesource.com/platform/bionic/+/808d176e7e0dd727c7f929622ec017f6e065c582/libc/arch-arm64/bionic/setjmp.S#49
+
+The architecture's call and return instructions (``bl`` and ``ret``) operate on
+a register rather than the stack, which means that leaf functions are generally
+protected from return address overwrites even without ShadowCallStack.
Usage
=====
@@ -132,17 +186,7 @@ The following example code:
return bar() + 1;
}
-Generates the following x86_64 assembly when compiled with ``-O2``:
-
-.. code-block:: gas
-
- push %rax
- callq bar
- add $0x1,%eax
- pop %rcx
- retq
-
-or the following aarch64 assembly:
+Generates the following aarch64 assembly when compiled with ``-O2``:
.. code-block:: none
@@ -153,33 +197,7 @@ or the following aarch64 assembly:
ldp x29, x30, [sp], #16
ret
-
-Adding ``-fsanitize=shadow-call-stack`` would output the following x86_64
-assembly:
-
-.. code-block:: gas
-
- mov (%rsp),%r10
- xor %r11,%r11
- addq $0x8,%gs:(%r11)
- mov %gs:(%r11),%r11
- mov %r10,%gs:(%r11)
- push %rax
- callq bar
- add $0x1,%eax
- pop %rcx
- xor %r11,%r11
- mov %gs:(%r11),%r10
- mov %gs:(%r10),%r10
- subq $0x8,%gs:(%r11)
- cmp %r10,(%rsp)
- jne trap
- retq
-
- trap:
- ud2
-
-or the following aarch64 assembly:
+Adding ``-fsanitize=shadow-call-stack`` would output the following assembly:
.. code-block:: none
diff --git a/docs/ThreadSanitizer.rst b/docs/ThreadSanitizer.rst
index 0d039bd5b2..ca5dfaafb4 100644
--- a/docs/ThreadSanitizer.rst
+++ b/docs/ThreadSanitizer.rst
@@ -19,9 +19,11 @@ Supported Platforms
ThreadSanitizer is supported on the following OS:
-* Linux
-* NetBSD
+* Android aarch64, x86_64
+* Darwin arm64, x86_64
* FreeBSD
+* Linux aarch64, x86_64, powerpc64, powerpc64le
+* NetBSD
Support for other 64-bit architectures is possible, contributions are welcome.
Support for 32-bit platforms is problematic and is not planned.
diff --git a/docs/Toolchain.rst b/docs/Toolchain.rst
index 3540708a38..da65f14597 100644
--- a/docs/Toolchain.rst
+++ b/docs/Toolchain.rst
@@ -117,7 +117,7 @@ Clang can be configured to use one of several different linkers:
* GNU ld
* GNU gold
-* LLVM's `lld <http://lld.llvm.org>`_
+* LLVM's `lld <https://lld.llvm.org>`_
* MSVC's link.exe
Link-time optimization is natively supported by lld, and supported via
@@ -164,7 +164,7 @@ other targets, compiler-rt is used by default.
compiler-rt (LLVM)
^^^^^^^^^^^^^^^^^^
-`LLVM's compiler runtime library <http://compiler-rt.llvm.org/>`_ provides a
+`LLVM's compiler runtime library <https://compiler-rt.llvm.org/>`_ provides a
complete set of runtime library functions containing all functions that
Clang will implicitly call, in ``libclang_rt.builtins.<arch>.a``.
@@ -222,21 +222,15 @@ Unwind library
The unwind library provides a family of ``_Unwind_*`` functions implementing
the language-neutral stack unwinding portion of the Itanium C++ ABI
-(`Level I <http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-abi>`_).
+(`Level I <https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-abi>`_).
It is a dependency of the C++ ABI library, and sometimes is a dependency
of other runtimes.
libunwind (LLVM)
^^^^^^^^^^^^^^^^
-LLVM's unwinder library can be obtained from subversion:
-
-.. code-block:: console
-
- llvm-src$ svn co https://llvm.org/svn/llvm-project/libunwind/trunk projects/libunwind
-
-When checked out into projects/libunwind within an LLVM checkout,
-it should be automatically picked up by the LLVM build system.
+LLVM's unwinder library is part of the llvm-project git repository. To
+build it, pass ``-DLLVM_ENABLE_PROJECTS=libunwind`` to the cmake invocation.
If using libc++abi, you may need to configure it to use libunwind
rather than libgcc_s by passing ``-DLIBCXXABI_USE_LLVM_UNWINDER=YES``
@@ -254,7 +248,7 @@ libunwind (nongnu.org)
^^^^^^^^^^^^^^^^^^^^^^
This is another implementation of the libunwind specification.
-See `libunwind (nongnu.org) <http://www.nongnu.org/libunwind>`_.
+See `libunwind (nongnu.org) <https://www.nongnu.org/libunwind>`_.
libunwind (PathScale)
^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +273,7 @@ C standard library
------------------
Clang supports a wide variety of
-`C standard library <http://en.cppreference.com/w/c>`_
+`C standard library <https://en.cppreference.com/w/c>`_
implementations.
C++ ABI library
@@ -288,9 +282,9 @@ C++ ABI library
The C++ ABI library provides an implementation of the library portion of
the Itanium C++ ABI, covering both the
`support functionality in the main Itanium C++ ABI document
-<http://itanium-cxx-abi.github.io/cxx-abi/abi.html>`_ and
+<https://itanium-cxx-abi.github.io/cxx-abi/abi.html>`_ and
`Level II of the exception handling support
-<http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#cxx-abi>`_.
+<https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#cxx-abi>`_.
References to the functions and objects in this library are implicitly
generated by Clang when compiling C++ code.
@@ -306,7 +300,7 @@ available:
libc++abi (LLVM)
^^^^^^^^^^^^^^^^
-`libc++abi <http://libcxxabi.llvm.org/>`_ is LLVM's implementation of this
+`libc++abi <https://libcxxabi.llvm.org/>`_ is LLVM's implementation of this
specification.
libsupc++ (GNU)
@@ -332,12 +326,12 @@ C++ standard library
--------------------
Clang supports use of either LLVM's libc++ or GCC's libstdc++ implementation
-of the `C++ standard library <http://en.cppreference.com/w/cpp>`_.
+of the `C++ standard library <https://en.cppreference.com/w/cpp>`_.
libc++ (LLVM)
^^^^^^^^^^^^^
-`libc++ <http://libcxx.llvm.org/>`_ is LLVM's implementation of the C++
+`libc++ <https://libcxx.llvm.org/>`_ is LLVM's implementation of the C++
standard library, aimed at being a complete implementation of the C++
standards from C++11 onwards.
diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst
index 3700d4962d..1e06a181b2 100644
--- a/docs/UndefinedBehaviorSanitizer.rst
+++ b/docs/UndefinedBehaviorSanitizer.rst
@@ -338,4 +338,4 @@ More Information
<http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html>`_
* From John Regehr's *Embedded in Academia* blog:
`A Guide to Undefined Behavior in C and C++
- <http://blog.regehr.org/archives/213>`_
+ <https://blog.regehr.org/archives/213>`_
diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst
index 7634d24eb5..88cb72c9b6 100644
--- a/docs/UsersManual.rst
+++ b/docs/UsersManual.rst
@@ -15,8 +15,8 @@ programming languages, aiming to be the best in class implementation of
these languages. Clang builds on the LLVM optimizer and code generator,
allowing it to provide high-quality optimization and code generation
support for many targets. For more general information, please see the
-`Clang Web Site <http://clang.llvm.org>`_ or the `LLVM Web
-Site <http://llvm.org>`_.
+`Clang Web Site <https://clang.llvm.org>`_ or the `LLVM Web
+Site <https://llvm.org>`_.
This document describes important notes about using Clang as a compiler
for an end-user, documenting the supported features, command line
@@ -994,7 +994,7 @@ information.
Precompiled Headers
-------------------
-`Precompiled headers <http://en.wikipedia.org/wiki/Precompiled_header>`__
+`Precompiled headers <https://en.wikipedia.org/wiki/Precompiled_header>`_
are a general approach employed by many compilers to reduce compilation
time. The underlying motivation of the approach is that it is common for
the same (and often large) header files to be included by multiple
@@ -1482,7 +1482,7 @@ usual build cycle when using sample profilers for optimization:
3. Convert the collected profile data to LLVM's sample profile format.
This is currently supported via the AutoFDO converter ``create_llvm_prof``.
- It is available at http://github.com/google/autofdo. Once built and
+ It is available at https://github.com/google/autofdo. Once built and
installed, you can convert the ``perf.data`` file to LLVM using
the command:
@@ -1521,12 +1521,12 @@ read by the backend. LLVM supports three different sample profile formats:
2. Binary encoding. This uses a more efficient encoding that yields smaller
profile files. This is the format generated by the ``create_llvm_prof`` tool
- in http://github.com/google/autofdo.
+ in https://github.com/google/autofdo.
3. GCC encoding. This is based on the gcov format, which is accepted by GCC. It
is only interesting in environments where GCC and Clang co-exist. This
encoding is only generated by the ``create_gcov`` tool in
- http://github.com/google/autofdo. It can be read by LLVM and
+ https://github.com/google/autofdo. It can be read by LLVM and
``llvm-profdata``, but it cannot be generated by either.
If you are using Linux Perf to generate sampling profiles, you can use the
@@ -1745,7 +1745,8 @@ controlled by the GCC-compatible flags ``-fprofile-generate`` and
``-fprofile-use``. Although these flags are semantically equivalent to
their GCC counterparts, they *do not* handle GCC-compatible profiles.
They are only meant to implement GCC's semantics with respect to
-profile creation and use.
+profile creation and use. Flag ``-fcs-profile-generate`` also instruments
+programs using the same instrumentation method as ``-fprofile-generate``.
.. option:: -fprofile-generate[=<dirname>]
@@ -1778,6 +1779,45 @@ profile creation and use.
``LLVM_PROFILE_FILE`` can still be used to override
the directory and filename for the profile file at runtime.
+.. option:: -fcs-profile-generate[=<dirname>]
+
+ The ``-fcs-profile-generate`` and ``-fcs-profile-generate=`` flags will use
+ the same instrumentation method, and generate the same profile as in the
+ ``-fprofile-generate`` and ``-fprofile-generate=`` flags. The difference is
+ that the instrumentation is performed after inlining so that the resulted
+ profile has a better context sensitive information. They cannot be used
+ together with ``-fprofile-generate`` and ``-fprofile-generate=`` flags.
+ They are typically used in conjunction with ``-fprofile-use`` flag.
+ The profile generated by ``-fcs-profile-generate`` and ``-fprofile-generate``
+ can be merged by llvm-profdata. A use example:
+
+ .. code-block:: console
+
+ $ clang++ -O2 -fprofile-generate=yyy/zzz code.cc -o code
+ $ ./code
+ $ llvm-profdata merge -output=code.profdata yyy/zzz/
+
+ The first few steps are the same as that in ``-fprofile-generate``
+ compilation. Then perform a second round of instrumentation.
+
+ .. code-block:: console
+
+ $ clang++ -O2 -fprofile-use=code.profdata -fcs-profile-generate=sss/ttt \
+ -o cs_code
+ $ ./cs_code
+ $ llvm-profdata merge -output=cs_code.profdata sss/ttt code.profdata
+
+ The resulted ``cs_code.prodata`` combines ``code.profdata`` and the profile
+ generated from binary ``cs_code``. Profile ``cs_code.profata`` can be used by
+ ``-fprofile-use`` compilaton.
+
+ .. code-block:: console
+
+ $ clang++ -O2 -fprofile-use=cs_code.profdata
+
+ The above command will read both profiles to the compiler at the identical
+ point of instrumenations.
+
.. option:: -fprofile-use[=<pathname>]
Without any other arguments, ``-fprofile-use`` behaves identically to
@@ -1831,9 +1871,9 @@ The profile remapping file is a text file containing lines of the form
where ``fragmentkind`` is one of ``name``, ``type``, or ``encoding``,
indicating whether the following mangled name fragments are
-<`name <http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.name>`_>s,
-<`type <http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.type>`_>s, or
-<`encoding <http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.encoding>`_>s,
+<`name <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.name>`_>s,
+<`type <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.type>`_>s, or
+<`encoding <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.encoding>`_>s,
respectively.
Blank lines and lines starting with ``#`` are ignored.
@@ -2829,7 +2869,7 @@ compatibility with the Visual C++ compiler, cl.exe.
To enable clang-cl to find system headers, libraries, and the linker when run
from the command-line, it should be executed inside a Visual Studio Native Tools
Command Prompt or a regular Command Prompt where the environment has been set
-up using e.g. `vcvarsall.bat <http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
+up using e.g. `vcvarsall.bat <https://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
clang-cl can also be used from inside Visual Studio by selecting the LLVM
Platform Toolset. The toolset is not part of the installer, but may be installed
diff --git a/docs/analyzer/checkers.rst b/docs/analyzer/checkers.rst
new file mode 100644
index 0000000000..b13d4d04d4
--- /dev/null
+++ b/docs/analyzer/checkers.rst
@@ -0,0 +1,2034 @@
+==================
+Available Checkers
+==================
+
+The analyzer performs checks that are categorized into families or "checkers".
+
+The default set of checkers covers a variety of checks targeted at finding security and API usage bugs,
+dead code, and other logic errors. See the :ref:`default-checkers` checkers list below.
+
+In addition to these, the analyzer contains a number of :ref:`alpha-checkers` (aka *alpha* checkers).
+These checkers are under development and are switched off by default. They may crash or emit a higher number of false positives.
+
+The :ref:`debug-checkers` package contains checkers for analyzer developers for debugging purposes.
+
+.. contents:: Table of Contents
+ :depth: 4
+
+
+.. _default-checkers:
+
+Default Checkers
+----------------
+
+.. _core-checkers:
+
+core
+^^^^
+Models core language features and contains general-purpose checkers such as division by zero,
+null pointer dereference, usage of uninitialized values, etc.
+*These checkers must be always switched on as other checker rely on them.*
+
+core.CallAndMessage (C, C++, ObjC)
+""""""""""""""""""""""""""""""""""
+ Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers).
+
+.. literalinclude:: checkers/callandmessage_example.c
+ :language: objc
+
+core.DivideZero (C, C++, ObjC)
+""""""""""""""""""""""""""""""
+ Check for division by zero.
+
+.. literalinclude:: checkers/dividezero_example.c
+ :language: c
+
+core.NonNullParamChecker (C, C++, ObjC)
+"""""""""""""""""""""""""""""""""""""""
+Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute.
+
+.. code-block:: cpp
+
+ int f(int *p) __attribute__((nonnull));
+
+ void test(int *p) {
+ if (!p)
+ f(p); // warn
+ }
+
+core.NullDereference (C, C++, ObjC)
+"""""""""""""""""""""""""""""""""""
+Check for dereferences of null pointers.
+
+.. code-block:: objc
+
+ // C
+ void test(int *p) {
+ if (p)
+ return;
+
+ int x = p[0]; // warn
+ }
+
+ // C
+ void test(int *p) {
+ if (!p)
+ *p = 0; // warn
+ }
+
+ // C++
+ class C {
+ public:
+ int x;
+ };
+
+ void test() {
+ C *pc = 0;
+ int k = pc->x; // warn
+ }
+
+ // Objective-C
+ @interface MyClass {
+ @public
+ int x;
+ }
+ @end
+
+ void test() {
+ MyClass *obj = 0;
+ obj->x = 1; // warn
+ }
+
+core.StackAddressEscape (C)
+"""""""""""""""""""""""""""
+Check that addresses to stack memory do not escape the function.
+
+.. code-block:: c
+
+ char const *p;
+
+ void test() {
+ char const str[] = "string";
+ p = str; // warn
+ }
+
+ void* test() {
+ return __builtin_alloca(12); // warn
+ }
+
+ void test() {
+ static int *x;
+ int y;
+ x = &y; // warn
+ }
+
+
+core.UndefinedBinaryOperatorResult (C)
+""""""""""""""""""""""""""""""""""""""
+Check for undefined results of binary operators.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ int y = x + 1; // warn: left operand is garbage
+ }
+
+core.VLASize (C)
+""""""""""""""""
+Check for declarations of Variable Length Arrays of undefined or zero size.
+
+ Check for declarations of VLA of undefined or zero size.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ int vla1[x]; // warn: garbage as size
+ }
+
+ void test() {
+ int x = 0;
+ int vla2[x]; // warn: zero size
+ }
+
+core.uninitialized.ArraySubscript (C)
+"""""""""""""""""""""""""""""""""""""
+Check for uninitialized values used as array subscripts.
+
+.. code-block:: c
+
+ void test() {
+ int i, a[10];
+ int x = a[i]; // warn: array subscript is undefined
+ }
+
+core.uninitialized.Assign (C)
+"""""""""""""""""""""""""""""
+Check for assigning uninitialized values.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ x |= 1; // warn: left expression is uninitialized
+ }
+
+core.uninitialized.Branch (C)
+"""""""""""""""""""""""""""""
+Check for uninitialized values used as branch conditions.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ if (x) // warn
+ return;
+ }
+
+core.uninitialized.CapturedBlockVariable (C)
+""""""""""""""""""""""""""""""""""""""""""""
+Check for blocks that capture uninitialized values.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ ^{ int y = x; }(); // warn
+ }
+
+core.uninitialized.UndefReturn (C)
+""""""""""""""""""""""""""""""""""
+Check for uninitialized values being returned to the caller.
+
+.. code-block:: c
+
+ int test() {
+ int x;
+ return x; // warn
+ }
+
+.. _cplusplus-checkers:
+
+
+cpluslus
+^^^^^^^^
+
+C++ Checkers.
+
+cplusplus.InnerPointer
+""""""""""""""""""""""
+Check for inner pointers of C++ containers used after re/deallocation.
+
+cplusplus.NewDelete (C++)
+"""""""""""""""""""""""""
+Check for double-free and use-after-free problems. Traces memory managed by new/delete.
+
+.. literalinclude:: checkers/newdelete_example.cpp
+ :language: cpp
+
+cplusplus.NewDeleteLeaks (C++)
+""""""""""""""""""""""""""""""
+Check for memory leaks. Traces memory managed by new/delete.
+
+.. code-block:: cpp
+
+ void test() {
+ int *p = new int;
+ } // warn
+
+
+cplusplus.SelfAssignment (C++)
+""""""""""""""""""""""""""""""
+Checks C++ copy and move assignment operators for self assignment.
+
+.. _deadcode-checkers:
+
+deadcode
+^^^^^^^^
+
+Dead Code Checkers.
+
+deadcode.DeadStores (C)
+"""""""""""""""""""""""
+Check for values stored to variables that are never read afterwards.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ x = 1; // warn
+ }
+
+.. _nullability-checkers:
+
+nullability
+^^^^^^^^^^^
+
+Objective C checkers that warn for null pointer passing and dereferencing errors.
+
+nullability.NullPassedToNonnull (ObjC)
+""""""""""""""""""""""""""""""""""""""
+Warns when a null pointer is passed to a pointer which has a _Nonnull type.
+
+.. code-block:: objc
+
+ if (name != nil)
+ return;
+ // Warning: nil passed to a callee that requires a non-null 1st parameter
+ NSString *greeting = [@"Hello " stringByAppendingString:name];
+
+nullability.NullReturnedFromNonnull (ObjC)
+""""""""""""""""""""""""""""""""""""""""""
+Warns when a null pointer is returned from a function that has _Nonnull return type.
+
+.. code-block:: objc
+
+ - (nonnull id)firstChild {
+ id result = nil;
+ if ([_children count] > 0)
+ result = _children[0];
+
+ // Warning: nil returned from a method that is expected
+ // to return a non-null value
+ return result;
+ }
+
+nullability.NullableDereferenced (ObjC)
+"""""""""""""""""""""""""""""""""""""""
+Warns when a nullable pointer is dereferenced.
+
+.. code-block:: objc
+
+ struct LinkedList {
+ int data;
+ struct LinkedList *next;
+ };
+
+ struct LinkedList * _Nullable getNext(struct LinkedList *l);
+
+ void updateNextData(struct LinkedList *list, int newData) {
+ struct LinkedList *next = getNext(list);
+ // Warning: Nullable pointer is dereferenced
+ next->data = 7;
+ }
+
+nullability.NullablePassedToNonnull (ObjC)
+""""""""""""""""""""""""""""""""""""""""""
+Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.
+
+.. code-block:: objc
+
+ typedef struct Dummy { int val; } Dummy;
+ Dummy *_Nullable returnsNullable();
+ void takesNonnull(Dummy *_Nonnull);
+
+ void test() {
+ Dummy *p = returnsNullable();
+ takesNonnull(p); // warn
+ }
+
+nullability.NullableReturnedFromNonnull (ObjC)
+""""""""""""""""""""""""""""""""""""""""""""""
+Warns when a nullable pointer is returned from a function that has _Nonnull return type.
+
+.. _optin-checkers:
+
+optin
+^^^^^
+
+Checkers for portability, performance or coding style specific rules.
+
+optin.cplusplus.UninitializedObject (C++)
+"""""""""""""""""""""""""""""""""""""""""
+
+This checker reports uninitialized fields in objects created after a constructor
+call. It doesn't only find direct uninitialized fields, but rather makes a deep
+inspection of the object, analyzing all of it's fields subfields.
+The checker regards inherited fields as direct fields, so one will recieve
+warnings for uninitialized inherited data members as well.
+
+.. code-block:: cpp
+
+ // With Pedantic and CheckPointeeInitialization set to true
+
+ struct A {
+ struct B {
+ int x; // note: uninitialized field 'this->b.x'
+ // note: uninitialized field 'this->bptr->x'
+ int y; // note: uninitialized field 'this->b.y'
+ // note: uninitialized field 'this->bptr->y'
+ };
+ int *iptr; // note: uninitialized pointer 'this->iptr'
+ B b;
+ B *bptr;
+ char *cptr; // note: uninitialized pointee 'this->cptr'
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // warning: 6 uninitialized fields
+ // after the constructor call
+ }
+
+ // With Pedantic set to false and
+ // CheckPointeeInitialization set to true
+ // (every field is uninitialized)
+
+ struct A {
+ struct B {
+ int x;
+ int y;
+ };
+ int *iptr;
+ B b;
+ B *bptr;
+ char *cptr;
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // no warning
+ }
+
+ // With Pedantic set to true and
+ // CheckPointeeInitialization set to false
+ // (pointees are regarded as initialized)
+
+ struct A {
+ struct B {
+ int x; // note: uninitialized field 'this->b.x'
+ int y; // note: uninitialized field 'this->b.y'
+ };
+ int *iptr; // note: uninitialized pointer 'this->iptr'
+ B b;
+ B *bptr;
+ char *cptr;
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // warning: 3 uninitialized fields
+ // after the constructor call
+ }
+
+
+**Options**
+
+This checker has several options which can be set from command line (e.g.
+``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``):
+
+* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for
+ objects that don't have at least one initialized field. Defaults to false.
+
+* ``NotesAsWarnings`` (boolean). If set to true, the checker will emit a
+ warning for each uninitalized field, as opposed to emitting one warning per
+ constructor call, and listing the uninitialized fields that belongs to it in
+ notes. *Defaults to false*.
+
+* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will
+ not analyze the pointee of pointer/reference fields, and will only check
+ whether the object itself is initialized. *Defaults to false*.
+
+* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze
+ structures that have a field with a name or type name that matches the given
+ pattern. *Defaults to ""*.
+
+optin.cplusplus.VirtualCall (C++)
+"""""""""""""""""""""""""""""""""
+Check virtual function calls during construction or destruction.
+
+.. code-block:: cpp
+
+ class A {
+ public:
+ A() {
+ f(); // warn
+ }
+ virtual void f();
+ };
+
+ class A {
+ public:
+ ~A() {
+ this->f(); // warn
+ }
+ virtual void f();
+ };
+
+optin.mpi.MPI-Checker (C)
+"""""""""""""""""""""""""
+Checks MPI code.
+
+.. code-block:: c
+
+ void test() {
+ double buf = 0;
+ MPI_Request sendReq1;
+ MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
+ 0, MPI_COMM_WORLD, &sendReq1);
+ } // warn: request 'sendReq1' has no matching wait.
+
+ void test() {
+ double buf = 0;
+ MPI_Request sendReq;
+ MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
+ MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
+ MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
+ MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
+ }
+
+ void missingNonBlocking() {
+ int rank = 0;
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Request sendReq1[10][10][10];
+ MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
+ }
+
+optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Check that NSLocalizedString macros include a comment for context.
+
+.. code-block:: objc
+
+ - (void)test {
+ NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
+ NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
+ NSString *string3 = NSLocalizedStringWithDefaultValue(
+ @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
+ }
+
+optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings.
+
+.. code-block:: objc
+
+ NSString *alarmText =
+ NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
+ if (!isEnabled) {
+ alarmText = @"Disabled";
+ }
+ UILabel *alarmStateLabel = [[UILabel alloc] init];
+
+ // Warning: User-facing text should use localized string macro
+ [alarmStateLabel setText:alarmText];
+
+optin.performance.GCDAntipattern
+""""""""""""""""""""""""""""""""
+Check for performance anti-patterns when using Grand Central Dispatch.
+
+optin.performance.Padding
+"""""""""""""""""""""""""
+Check for excessively padded structs.
+
+optin.portability.UnixAPI
+"""""""""""""""""""""""""
+Finds implementation-defined behavior in UNIX/Posix functions.
+
+
+.. _security-checkers:
+
+security
+^^^^^^^^
+
+Security related checkers.
+
+security.FloatLoopCounter (C)
+"""""""""""""""""""""""""""""
+Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).
+
+.. code-block:: c
+
+ void test() {
+ for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
+ }
+
+security.insecureAPI.UncheckedReturn (C)
+""""""""""""""""""""""""""""""""""""""""
+Warn on uses of functions whose return values must be always checked.
+
+.. code-block:: c
+
+ void test() {
+ setuid(1); // warn
+ }
+
+security.insecureAPI.bcmp (C)
+"""""""""""""""""""""""""""""
+Warn on uses of the 'bcmp' function.
+
+.. code-block:: c
+
+ void test() {
+ bcmp(ptr0, ptr1, n); // warn
+ }
+
+security.insecureAPI.bcopy (C)
+""""""""""""""""""""""""""""""
+Warn on uses of the 'bcopy' function.
+
+.. code-block:: c
+
+ void test() {
+ bcopy(src, dst, n); // warn
+ }
+
+security.insecureAPI.bzero (C)
+""""""""""""""""""""""""""""""
+Warn on uses of the 'bzero' function.
+
+.. code-block:: c
+
+ void test() {
+ bzero(ptr, n); // warn
+ }
+
+security.insecureAPI.getpw (C)
+""""""""""""""""""""""""""""""
+Warn on uses of the 'getpw' function.
+
+.. code-block:: c
+
+ void test() {
+ char buff[1024];
+ getpw(2, buff); // warn
+ }
+
+security.insecureAPI.gets (C)
+"""""""""""""""""""""""""""""
+Warn on uses of the 'gets' function.
+
+.. code-block:: c
+
+ void test() {
+ char buff[1024];
+ gets(buff); // warn
+ }
+
+security.insecureAPI.mkstemp (C)
+""""""""""""""""""""""""""""""""
+Warn when 'mkstemp' is passed fewer than 6 X's in the format string.
+
+.. code-block:: c
+
+ void test() {
+ mkstemp("XX"); // warn
+ }
+
+security.insecureAPI.mktemp (C)
+"""""""""""""""""""""""""""""""
+Warn on uses of the ``mktemp`` function.
+
+.. code-block:: c
+
+ void test() {
+ char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
+ }
+
+security.insecureAPI.rand (C)
+"""""""""""""""""""""""""""""
+Warn on uses of inferior random number generating functions (only if arc4random function is available):
+``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``.
+
+.. code-block:: c
+
+ void test() {
+ random(); // warn
+ }
+
+security.insecureAPI.strcpy (C)
+"""""""""""""""""""""""""""""""
+Warn on uses of the ``strcpy`` and ``strcat`` functions.
+
+.. code-block:: c
+
+ void test() {
+ char x[4];
+ char *y = "abcd";
+
+ strcpy(x, y); // warn
+ }
+
+
+security.insecureAPI.vfork (C)
+""""""""""""""""""""""""""""""
+ Warn on uses of the 'vfork' function.
+
+.. code-block:: c
+
+ void test() {
+ vfork(); // warn
+ }
+
+security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+ Warn on occurrences of unsafe or deprecated buffer handling functions, which now have a secure variant: ``sprintf, vsprintf, scanf, wscanf, fscanf, fwscanf, vscanf, vwscanf, vfscanf, vfwscanf, sscanf, swscanf, vsscanf, vswscanf, swprintf, snprintf, vswprintf, vsnprintf, memcpy, memmove, strncpy, strncat, memset``
+
+.. code-block:: c
+
+ void test() {
+ char buf [5];
+ strncpy(buf, "a", 1); // warn
+ }
+
+.. _unix-checkers:
+
+unix
+^^^^
+POSIX/Unix checkers.
+
+unix.API (C)
+""""""""""""
+Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.
+
+.. literalinclude:: checkers/unix_api_example.c
+ :language: c
+
+unix.Malloc (C)
+"""""""""""""""
+Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().
+
+.. literalinclude:: checkers/unix_malloc_example.c
+ :language: c
+
+unix.MallocSizeof (C)
+"""""""""""""""""""""
+Check for dubious ``malloc`` arguments involving ``sizeof``.
+
+.. code-block:: c
+
+ void test() {
+ long *p = malloc(sizeof(short));
+ // warn: result is converted to 'long *', which is
+ // incompatible with operand type 'short'
+ free(p);
+ }
+
+unix.MismatchedDeallocator (C, C++)
+"""""""""""""""""""""""""""""""""""
+Check for mismatched deallocators.
+
+.. literalinclude:: checkers/mismatched_deallocator_example.cpp
+ :language: c
+
+unix.Vfork (C)
+""""""""""""""
+Check for proper usage of ``vfork``.
+
+.. code-block:: c
+
+ int test(int x) {
+ pid_t pid = vfork(); // warn
+ if (pid != 0)
+ return 0;
+
+ switch (x) {
+ case 0:
+ pid = 1;
+ execl("", "", 0);
+ _exit(1);
+ break;
+ case 1:
+ x = 0; // warn: this assignment is prohibited
+ break;
+ case 2:
+ foo(); // warn: this function call is prohibited
+ break;
+ default:
+ return 0; // warn: return is prohibited
+ }
+
+ while(1);
+ }
+
+unix.cstring.BadSizeArg (C)
+"""""""""""""""""""""""""""
+Check the size argument passed into C string functions for common erroneous patterns. Use ``-Wno-strncat-size`` compiler option to mute other ``strncat``-related compiler warnings.
+
+.. code-block:: c
+
+ void test() {
+ char dest[3];
+ strncat(dest, """""""""""""""""""""""""*", sizeof(dest));
+ // warn: potential buffer overflow
+ }
+
+unix.cstrisng.NullArg (C)
+"""""""""""""""""""""""""
+Check for null pointers being passed as arguments to C string functions:
+``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp``.
+
+.. code-block:: c
+
+ int test() {
+ return strlen(0); // warn
+ }
+
+.. _osx-checkers:
+
+osx
+^^^
+OS X checkers.
+
+osx.API (C)
+"""""""""""
+Check for proper uses of various Apple APIs.
+
+.. code-block:: objc
+
+ void test() {
+ dispatch_once_t pred = 0;
+ dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
+ }
+
+osx.NumberObjectConversion (C, C++, ObjC)
+"""""""""""""""""""""""""""""""""""""""""
+Check for erroneous conversions of objects representing numbers into numbers.
+
+.. code-block:: objc
+
+ NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
+ // Warning: Comparing a pointer value of type 'NSNumber *'
+ // to a scalar integer value
+ if (photoCount > 0) {
+ [self displayPhotos];
+ }
+
+osx.ObjCProperty (ObjC)
+"""""""""""""""""""""""
+Check for proper uses of Objective-C properties.
+
+.. code-block:: objc
+
+ NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
+ // Warning: Comparing a pointer value of type 'NSNumber *'
+ // to a scalar integer value
+ if (photoCount > 0) {
+ [self displayPhotos];
+ }
+
+
+osx.SecKeychainAPI (C)
+""""""""""""""""""""""
+Check for proper uses of Secure Keychain APIs.
+
+.. literalinclude:: checkers/seckeychainapi_example.m
+ :language: objc
+
+osx.cocoa.AtSync (ObjC)
+"""""""""""""""""""""""
+Check for nil pointers used as mutexes for @synchronized.
+
+.. code-block:: objc
+
+ void test(id x) {
+ if (!x)
+ @synchronized(x) {} // warn: nil value used as mutex
+ }
+
+ void test() {
+ id y;
+ @synchronized(y) {} // warn: uninitialized value used as mutex
+ }
+
+osx.cocoa.AutoreleaseWrite
+""""""""""""""""""""""""""
+Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.
+
+osx.cocoa.ClassRelease (ObjC)
+"""""""""""""""""""""""""""""
+Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
+
+.. code-block:: objc
+
+ @interface MyClass : NSObject
+ @end
+
+ void test(void) {
+ [MyClass release]; // warn
+ }
+
+osx.cocoa.Dealloc (ObjC)
+""""""""""""""""""""""""
+Warn about Objective-C classes that lack a correct implementation of -dealloc
+
+.. literalinclude:: checkers/dealloc_example.m
+ :language: objc
+
+osx.cocoa.IncompatibleMethodTypes (ObjC)
+""""""""""""""""""""""""""""""""""""""""
+Warn about Objective-C method signatures with type incompatibilities.
+
+.. code-block:: objc
+
+ @interface MyClass1 : NSObject
+ - (int)foo;
+ @end
+
+ @implementation MyClass1
+ - (int)foo { return 1; }
+ @end
+
+ @interface MyClass2 : MyClass1
+ - (float)foo;
+ @end
+
+ @implementation MyClass2
+ - (float)foo { return 1.0; } // warn
+ @end
+
+osx.cocoa.Loops
+"""""""""""""""
+Improved modeling of loops using Cocoa collection types.
+
+osx.cocoa.MissingSuperCall (ObjC)
+"""""""""""""""""""""""""""""""""
+Warn about Objective-C methods that lack a necessary call to super.
+
+.. code-block:: objc
+
+ @interface Test : UIViewController
+ @end
+ @implementation test
+ - (void)viewDidLoad {} // warn
+ @end
+
+
+osx.cocoa.NSAutoreleasePool (ObjC)
+""""""""""""""""""""""""""""""""""
+Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
+
+.. code-block:: objc
+
+ void test() {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [pool release]; // warn
+ }
+
+osx.cocoa.NSError (ObjC)
+""""""""""""""""""""""""
+Check usage of NSError parameters.
+
+.. code-block:: objc
+
+ @interface A : NSObject
+ - (void)foo:(NSError """""""""""""""""""""""")error;
+ @end
+
+ @implementation A
+ - (void)foo:(NSError """""""""""""""""""""""")error {
+ // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void
+ // return value
+ }
+ @end
+
+ @interface A : NSObject
+ - (BOOL)foo:(NSError """""""""""""""""""""""")error;
+ @end
+
+ @implementation A
+ - (BOOL)foo:(NSError """""""""""""""""""""""")error {
+ *error = 0; // warn: potential null dereference
+ return 0;
+ }
+ @end
+
+osx.cocoa.NilArg (ObjC)
+"""""""""""""""""""""""
+Check for prohibited nil arguments to ObjC method calls.
+
+ - caseInsensitiveCompare:
+ - compare:
+ - compare:options:
+ - compare:options:range:
+ - compare:options:range:locale:
+ - componentsSeparatedByCharactersInSet:
+ - initWithFormat:
+
+.. code-block:: objc
+
+ NSComparisonResult test(NSString *s) {
+ NSString *aString = nil;
+ return [s caseInsensitiveCompare:aString];
+ // warn: argument to 'NSString' method
+ // 'caseInsensitiveCompare:' cannot be nil
+ }
+
+
+osx.cocoa.NonNilReturnValue
+"""""""""""""""""""""""""""
+Models the APIs that are guaranteed to return a non-nil value.
+
+osx.cocoa.ObjCGenerics (ObjC)
+"""""""""""""""""""""""""""""
+Check for type errors when using Objective-C generics.
+
+.. code-block:: objc
+
+ NSMutableArray *names = [NSMutableArray array];
+ NSMutableArray *birthDates = names;
+
+ // Warning: Conversion from value of type 'NSDate *'
+ // to incompatible type 'NSString *'
+ [birthDates addObject: [NSDate date]];
+
+osx.cocoa.RetainCount (ObjC)
+""""""""""""""""""""""""""""
+Check for leaks and improper reference count management
+
+.. code-block:: objc
+
+ void test() {
+ NSString *s = [[NSString alloc] init]; // warn
+ }
+
+ CFStringRef test(char *bytes) {
+ return CFStringCreateWithCStringNoCopy(
+ 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
+ }
+
+
+osx.cocoa.RunLoopAutoreleaseLeak
+""""""""""""""""""""""""""""""""
+Check for leaked memory in autorelease pools that will never be drained.
+
+osx.cocoa.SelfInit (ObjC)
+"""""""""""""""""""""""""
+Check that 'self' is properly initialized inside an initializer method.
+
+.. code-block:: objc
+
+ @interface MyObj : NSObject {
+ id x;
+ }
+ - (id)init;
+ @end
+
+ @implementation MyObj
+ - (id)init {
+ [super init];
+ x = 0; // warn: instance variable used while 'self' is not
+ // initialized
+ return 0;
+ }
+ @end
+
+ @interface MyObj : NSObject
+ - (id)init;
+ @end
+
+ @implementation MyObj
+ - (id)init {
+ [super init];
+ return self; // warn: returning uninitialized 'self'
+ }
+ @end
+
+osx.cocoa.SuperDealloc (ObjC)
+"""""""""""""""""""""""""""""
+Warn about improper use of '[super dealloc]' in Objective-C.
+
+.. code-block:: objc
+
+ @interface SuperDeallocThenReleaseIvarClass : NSObject {
+ NSObject *_ivar;
+ }
+ @end
+
+ @implementation SuperDeallocThenReleaseIvarClass
+ - (void)dealloc {
+ [super dealloc];
+ [_ivar release]; // warn
+ }
+ @end
+
+osx.cocoa.UnusedIvars (ObjC)
+""""""""""""""""""""""""""""
+Warn about private ivars that are never used.
+
+.. code-block:: objc
+
+ @interface MyObj : NSObject {
+ @private
+ id x; // warn
+ }
+ @end
+
+ @implementation MyObj
+ @end
+
+osx.cocoa.VariadicMethodTypes (ObjC)
+""""""""""""""""""""""""""""""""""""
+Check for passing non-Objective-C types to variadic collection
+initialization methods that expect only Objective-C types.
+
+.. code-block:: objc
+
+ void test() {
+ [NSSet setWithObjects:@"Foo", "Bar", nil];
+ // warn: argument should be an ObjC pointer type, not 'char *'
+ }
+
+osx.coreFoundation.CFError (C)
+""""""""""""""""""""""""""""""
+Check usage of CFErrorRef* parameters
+
+.. code-block:: c
+
+ void test(CFErrorRef *error) {
+ // warn: function accepting CFErrorRef* should have a
+ // non-void return
+ }
+
+ int foo(CFErrorRef *error) {
+ *error = 0; // warn: potential null dereference
+ return 0;
+ }
+
+osx.coreFoundation.CFNumber (C)
+"""""""""""""""""""""""""""""""
+Check for proper uses of CFNumber APIs.
+
+.. code-block:: c
+
+ CFNumberRef test(unsigned char x) {
+ return CFNumberCreate(0, kCFNumberSInt16Type, &x);
+ // warn: 8 bit integer is used to initialize a 16 bit integer
+ }
+
+osx.coreFoundation.CFRetainRelease (C)
+""""""""""""""""""""""""""""""""""""""
+Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
+
+.. code-block:: c
+
+ void test(CFTypeRef p) {
+ if (!p)
+ CFRetain(p); // warn
+ }
+
+ void test(int x, CFTypeRef p) {
+ if (p)
+ return;
+
+ CFRelease(p); // warn
+ }
+
+osx.coreFoundation.containers.OutOfBounds (C)
+"""""""""""""""""""""""""""""""""""""""""""""
+Checks for index out-of-bounds when using 'CFArray' API.
+
+.. code-block:: c
+
+ void test() {
+ CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
+ CFArrayGetValueAtIndex(A, 0); // warn
+ }
+
+osx.coreFoundation.containers.PointerSizedValues (C)
+""""""""""""""""""""""""""""""""""""""""""""""""""""
+Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
+
+.. code-block:: c
+
+ void test() {
+ int x[] = { 1 };
+ CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,
+ &kCFTypeArrayCallBacks); // warn
+ }
+
+
+.. _alpha-checkers:
+
+Experimental Checkers
+---------------------
+
+*These are checkers with known issues or limitations that keep them from being on by default. They are likely to have false positives. Bug reports and especially patches are welcome.*
+
+alpha.clone
+^^^^^^^^^^^
+
+alpha.clone.CloneChecker (C, C++, ObjC)
+"""""""""""""""""""""""""""""""""""""""
+Reports similar pieces of code.
+
+.. code-block:: c
+
+ void log();
+
+ int max(int a, int b) { // warn
+ log();
+ if (a > b)
+ return a;
+ return b;
+ }
+
+ int maxClone(int x, int y) { // similar code here
+ log();
+ if (x > y)
+ return x;
+ return y;
+ }
+
+alpha.core.BoolAssignment (ObjC)
+""""""""""""""""""""""""""""""""
+Warn about assigning non-{0,1} values to boolean variables.
+
+.. code-block:: objc
+
+ void test() {
+ BOOL b = -1; // warn
+ }
+
+alpha.core
+^^^^^^^^^^
+
+alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""
+Check for logical errors for function calls and Objective-C
+message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
+
+.. code-block:: c
+
+ void test(void) {
+ int t;
+ int &p = t;
+ int &s = p;
+ int &q = s;
+ foo(q); // warn
+ }
+
+ void test(void) {
+ int x;
+ foo(&x); // warn
+ }
+
+alpha.core.CastSize (C)
+"""""""""""""""""""""""
+Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
+
+.. code-block:: c
+
+ void test() {
+ int *x = (int *) malloc(11); // warn
+ }
+
+alpha.core.CastToStruct (C, C++)
+""""""""""""""""""""""""""""""""
+Check for cast from non-struct pointer to struct pointer.
+
+.. code-block:: cpp
+
+ // C
+ struct s {};
+
+ void test(int *p) {
+ struct s *ps = (struct s *) p; // warn
+ }
+
+ // C++
+ class c {};
+
+ void test(int *p) {
+ c *pc = (c *) p; // warn
+ }
+
+alpha.core.Conversion (C, C++, ObjC)
+""""""""""""""""""""""""""""""""""""
+Loss of sign/precision in implicit conversions.
+
+.. code-block:: c
+
+ void test(unsigned U, signed S) {
+ if (S > 10) {
+ if (U < S) {
+ }
+ }
+ if (S < -10) {
+ if (U < S) { // warn (loss of sign)
+ }
+ }
+ }
+
+ void test() {
+ long long A = 1LL << 60;
+ short X = A; // warn (loss of precision)
+ }
+
+alpha.core.DynamicTypeChecker (ObjC)
+""""""""""""""""""""""""""""""""""""
+Check for cases where the dynamic and the static type of an object are unrelated.
+
+
+.. code-block:: objc
+
+ id date = [NSDate date];
+
+ // Warning: Object has a dynamic type 'NSDate *' which is
+ // incompatible with static type 'NSNumber *'"
+ NSNumber *number = date;
+ [number doubleValue];
+
+alpha.core.FixedAddr (C)
+""""""""""""""""""""""""
+Check for assignment of a fixed address to a pointer.
+
+.. code-block:: c
+
+ void test() {
+ int *p;
+ p = (int *) 0x10000; // warn
+ }
+
+alpha.core.IdenticalExpr (C, C++)
+"""""""""""""""""""""""""""""""""
+Warn about unintended use of identical expressions in operators.
+
+.. code-block:: cpp
+
+ // C
+ void test() {
+ int a = 5;
+ int b = a | 4 | a; // warn: identical expr on both sides
+ }
+
+ // C++
+ bool f(void);
+
+ void test(bool b) {
+ int i = 10;
+ if (f()) { // warn: true and false branches are identical
+ do {
+ i--;
+ } while (f());
+ } else {
+ do {
+ i--;
+ } while (f());
+ }
+ }
+
+alpha.core.PointerArithm (C)
+""""""""""""""""""""""""""""
+Check for pointer arithmetic on locations other than array elements.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ int *p;
+ p = &x + 1; // warn
+ }
+
+alpha.core.PointerSub (C)
+"""""""""""""""""""""""""
+Check for pointer subtractions on two pointers pointing to different memory chunks.
+
+.. code-block:: c
+
+ void test() {
+ int x, y;
+ int d = &y - &x; // warn
+ }
+
+alpha.core.SizeofPtr (C)
+""""""""""""""""""""""""
+Warn about unintended use of ``sizeof()`` on pointer expressions.
+
+.. code-block:: c
+
+ struct s {};
+
+ int test(struct s *p) {
+ return sizeof(p);
+ // warn: sizeof(ptr) can produce an unexpected result
+ }
+
+alpha.core.StackAddressAsyncEscape (C)
+""""""""""""""""""""""""""""""""""""""
+Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
+This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
+
+.. code-block:: c
+
+ dispatch_block_t test_block_inside_block_async_leak() {
+ int x = 123;
+ void (^inner)(void) = ^void(void) {
+ int y = x;
+ ++y;
+ };
+ void (^outer)(void) = ^void(void) {
+ int z = x;
+ ++z;
+ inner();
+ };
+ return outer; // warn: address of stack-allocated block is captured by a
+ // returned block
+ }
+
+alpha.core.TestAfterDivZero (C)
+"""""""""""""""""""""""""""""""
+Check for division by variable that is later compared against 0.
+Either the comparison is useless or there is division by zero.
+
+.. code-block:: c
+
+ void test(int x) {
+ var = 77 / x;
+ if (x == 0) { } // warn
+ }
+
+alpha.cplusplus
+^^^^^^^^^^^^^^^
+
+alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
+""""""""""""""""""""""""""""""""""""""""""""""
+Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
+
+.. code-block:: cpp
+
+ NonVirtual *create() {
+ NonVirtual *x = new NVDerived(); // note: conversion from derived to base
+ // happened here
+ return x;
+ }
+
+ void sink(NonVirtual *x) {
+ delete x; // warn: destruction of a polymorphic object with no virtual
+ // destructor
+ }
+
+alpha.cplusplus.EnumCastOutOfRange (C++)
+""""""""""""""""""""""""""""""""""""""""
+Check for integer to enumeration casts that could result in undefined values.
+
+.. code-block:: cpp
+
+ enum TestEnum {
+ A = 0
+ };
+
+ void foo() {
+ TestEnum t = static_cast(-1);
+ // warn: the value provided to the cast expression is not in
+ the valid range of values for the enum
+
+alpha.cplusplus.InvalidatedIterator (C++)
+"""""""""""""""""""""""""""""""""""""""""
+Check for use of invalidated iterators.
+
+.. code-block:: cpp
+
+ void bad_copy_assign_operator_list1(std::list &L1,
+ const std::list &L2) {
+ auto i0 = L1.cbegin();
+ L1 = L2;
+ *i0; // warn: invalidated iterator accessed
+ }
+
+
+alpha.cplusplus.IteratorRange (C++)
+"""""""""""""""""""""""""""""""""""
+Check for iterators used outside their valid ranges.
+
+.. code-block:: cpp
+
+ void simple_bad_end(const std::vector &v) {
+ auto i = v.end();
+ *i; // warn: iterator accessed outside of its range
+ }
+
+alpha.cplusplus.MismatchedIterator (C++)
+""""""""""""""""""""""""""""""""""""""""
+Check for use of iterators of different containers where iterators of the same container are expected.
+
+.. code-block:: cpp
+
+ void bad_insert3(std::vector &v1, std::vector &v2) {
+ v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
+ // using foreign
+ // iterator argument
+ v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
+ // different containers
+ // used where the same
+ // container is
+ // expected
+ v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
+ // different containers
+ // used where the same
+ // container is
+ // expected
+ }
+
+alpha.cplusplus.MisusedMovedObject (C++)
+""""""""""""""""""""""""""""""""""""""""
+Method calls on a moved-from object and copying a moved-from object will be reported.
+
+
+.. code-block:: cpp
+
+ struct A {
+ void foo() {}
+ };
+
+ void f() {
+ A a;
+ A b = std::move(a); // note: 'a' became 'moved-from' here
+ a.foo(); // warn: method call on a 'moved-from' object 'a'
+ }
+
+alpha.deadcode
+^^^^^^^^^^^^^^
+alpha.deadcode.UnreachableCode (C, C++)
+"""""""""""""""""""""""""""""""""""""""
+Check unreachable code.
+
+.. code-block:: cpp
+
+ // C
+ int test() {
+ int x = 1;
+ while(x);
+ return x; // warn
+ }
+
+ // C++
+ void test() {
+ int a = 2;
+
+ while (a > 1)
+ a--;
+
+ if (a > 1)
+ a++; // warn
+ }
+
+ // Objective-C
+ void test(id x) {
+ return;
+ [x retain]; // warn
+ }
+
+alpha.llvm
+^^^^^^^^^^
+
+alpha.llvm.Conventions
+""""""""""""""""""""""
+
+Check code for LLVM codebase conventions:
+
+* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
+* Clang AST nodes should not have fields that can allocate memory.
+
+
+alpha.osx
+^^^^^^^^^
+
+alpha.osx.cocoa.DirectIvarAssignment (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""
+Check for direct assignments to instance variables.
+
+
+.. code-block:: objc
+
+ @interface MyClass : NSObject {}
+ @property (readonly) id A;
+ - (void) foo;
+ @end
+
+ @implementation MyClass
+ - (void) foo {
+ _A = 0; // warn
+ }
+ @end
+
+alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Check for direct assignments to instance variables in
+the methods annotated with ``objc_no_direct_instance_variable_assignment``.
+
+.. code-block:: objc
+
+ @interface MyClass : NSObject {}
+ @property (readonly) id A;
+ - (void) fAnnotated __attribute__((
+ annotate("objc_no_direct_instance_variable_assignment")));
+ - (void) fNotAnnotated;
+ @end
+
+ @implementation MyClass
+ - (void) fAnnotated {
+ _A = 0; // warn
+ }
+ - (void) fNotAnnotated {
+ _A = 0; // no warn
+ }
+ @end
+
+
+alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""
+Check that the invalidatable instance variables are
+invalidated in the methods annotated with objc_instance_variable_invalidator.
+
+.. code-block:: objc
+
+ @protocol Invalidation <NSObject>
+ - (void) invalidate
+ __attribute__((annotate("objc_instance_variable_invalidator")));
+ @end
+
+ @interface InvalidationImpObj : NSObject <Invalidation>
+ @end
+
+ @interface SubclassInvalidationImpObj : InvalidationImpObj {
+ InvalidationImpObj *var;
+ }
+ - (void)invalidate;
+ @end
+
+ @implementation SubclassInvalidationImpObj
+ - (void) invalidate {}
+ @end
+ // warn: var needs to be invalidated or set to nil
+
+alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
+""""""""""""""""""""""""""""""""""""""""""""""""
+Check that the invalidation methods are present in classes that contain invalidatable instance variables.
+
+.. code-block:: objc
+
+ @protocol Invalidation <NSObject>
+ - (void)invalidate
+ __attribute__((annotate("objc_instance_variable_invalidator")));
+ @end
+
+ @interface NeedInvalidation : NSObject <Invalidation>
+ @end
+
+ @interface MissingInvalidationMethodDecl : NSObject {
+ NeedInvalidation *Var; // warn
+ }
+ @end
+
+ @implementation MissingInvalidationMethodDecl
+ @end
+
+alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Warns against using one vs. many plural pattern in code when generating localized strings.
+
+.. code-block:: objc
+
+ NSString *reminderText =
+ NSLocalizedString(@"None", @"Indicates no reminders");
+ if (reminderCount == 1) {
+ // Warning: Plural cases are not supported across all languages.
+ // Use a .stringsdict file instead
+ reminderText =
+ NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
+ } else if (reminderCount >= 2) {
+ // Warning: Plural cases are not supported across all languages.
+ // Use a .stringsdict file instead
+ reminderText =
+ [NSString stringWithFormat:
+ NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
+ reminderCount];
+ }
+
+alpha.security
+^^^^^^^^^^^^^^
+alpha.security.ArrayBound (C)
+"""""""""""""""""""""""""""""
+Warn about buffer overflows (older checker).
+
+.. code-block:: c
+
+ void test() {
+ char *s = "";
+ char c = s[1]; // warn
+ }
+
+ struct seven_words {
+ int c[7];
+ };
+
+ void test() {
+ struct seven_words a, *p;
+ p = &a;
+ p[0] = a;
+ p[1] = a;
+ p[2] = a; // warn
+ }
+
+ // note: requires unix.Malloc or
+ // alpha.unix.MallocWithAnnotations checks enabled.
+ void test() {
+ int *p = malloc(12);
+ p[3] = 4; // warn
+ }
+
+ void test() {
+ char a[2];
+ int *b = (int*)a;
+ b[1] = 3; // warn
+ }
+
+alpha.security.ArrayBoundV2 (C)
+"""""""""""""""""""""""""""""""
+Warn about buffer overflows (newer checker).
+
+.. code-block:: c
+
+ void test() {
+ char *s = "";
+ char c = s[1]; // warn
+ }
+
+ void test() {
+ int buf[100];
+ int *p = buf;
+ p = p + 99;
+ p[1] = 1; // warn
+ }
+
+ // note: compiler has internal check for this.
+ // Use -Wno-array-bounds to suppress compiler warning.
+ void test() {
+ int buf[100][100];
+ buf[0][-1] = 1; // warn
+ }
+
+ // note: requires alpha.security.taint check turned on.
+ void test() {
+ char s[] = "abc";
+ int x = getchar();
+ char c = s[x]; // warn: index is tainted
+ }
+
+alpha.security.MallocOverflow (C)
+"""""""""""""""""""""""""""""""""
+Check for overflows in the arguments to malloc().
+
+.. code-block:: c
+
+ void test(int n) {
+ void *p = malloc(n * sizeof(int)); // warn
+ }
+
+alpha.security.MmapWriteExec (C)
+""""""""""""""""""""""""""""""""
+Warn on mmap() calls that are both writable and executable.
+
+.. code-block:: c
+
+ void test(int n) {
+ void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+ // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
+ // exploitable memory regions, which could be overwritten with malicious
+ // code
+ }
+
+alpha.security.ReturnPtrRange (C)
+"""""""""""""""""""""""""""""""""
+Check for an out-of-bound pointer being returned to callers.
+
+.. code-block:: c
+
+ static int A[10];
+
+ int *test() {
+ int *p = A + 10;
+ return p; // warn
+ }
+
+ int test(void) {
+ int x;
+ return x; // warn: undefined or garbage returned
+ }
+
+alpha.security.taint.TaintPropagation (C, C++)
+""""""""""""""""""""""""""""""""""""""""""""""
+Generate taint information used by other checkers.
+A data is tainted when it comes from an unreliable source.
+
+.. code-block:: c
+
+ void test() {
+ char x = getchar(); // 'x' marked as tainted
+ system(&x); // warn: untrusted data is passed to a system call
+ }
+
+ // note: compiler internally checks if the second param to
+ // sprintf is a string literal or not.
+ // Use -Wno-format-security to suppress compiler warning.
+ void test() {
+ char s[10], buf[10];
+ fscanf(stdin, "%s", s); // 's' marked as tainted
+
+ sprintf(buf, s); // warn: untrusted data as a format string
+ }
+
+ void test() {
+ size_t ts;
+ scanf("%zd", &ts); // 'ts' marked as tainted
+ int *p = (int *)malloc(ts * sizeof(int));
+ // warn: untrusted data as buffer size
+ }
+
+alpha.unix
+^^^^^^^^^^^
+
+alpha.unix.BlockInCriticalSection (C)
+"""""""""""""""""""""""""""""""""""""
+Check for calls to blocking functions inside a critical section.
+Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
+`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
+
+.. code-block:: c
+
+ void test() {
+ std::mutex m;
+ m.lock();
+ sleep(3); // warn: a blocking function sleep is called inside a critical
+ // section
+ m.unlock();
+ }
+
+alpha.unix.Chroot (C)
+"""""""""""""""""""""
+Check improper use of chroot.
+
+.. code-block:: c
+
+ void f();
+
+ void test() {
+ chroot("/usr/local");
+ f(); // warn: no call of chdir("/") immediately after chroot
+ }
+
+alpha.unix.PthreadLock (C)
+""""""""""""""""""""""""""
+Simple lock -> unlock checker.
+Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
+``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
+lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
+
+
+.. code-block:: c
+
+ pthread_mutex_t mtx;
+
+ void test() {
+ pthread_mutex_lock(&mtx);
+ pthread_mutex_lock(&mtx);
+ // warn: this lock has already been acquired
+ }
+
+ lck_mtx_t lck1, lck2;
+
+ void test() {
+ lck_mtx_lock(&lck1);
+ lck_mtx_lock(&lck2);
+ lck_mtx_unlock(&lck1);
+ // warn: this was not the most recently acquired lock
+ }
+
+ lck_mtx_t lck1, lck2;
+
+ void test() {
+ if (lck_mtx_try_lock(&lck1) == 0)
+ return;
+
+ lck_mtx_lock(&lck2);
+ lck_mtx_unlock(&lck1);
+ // warn: this was not the most recently acquired lock
+ }
+
+alpha.unix.SimpleStream (C)
+"""""""""""""""""""""""""""
+Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
+(demo checker, the subject of the demo (`Slides <http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
+`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
+`2012 LLVM Developers' Meeting <http://llvm.org/devmtg/2012-11/>`_).
+
+.. code-block:: c
+
+ void test() {
+ FILE *F = fopen("myfile.txt", "w");
+ } // warn: opened file is never closed
+
+ void test() {
+ FILE *F = fopen("myfile.txt", "w");
+
+ if (F)
+ fclose(F);
+
+ fclose(F); // warn: closing a previously closed file stream
+ }
+
+alpha.unix.Stream (C)
+"""""""""""""""""""""
+Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
+``fsetpos, clearerr, feof, ferror, fileno``.
+
+.. code-block:: c
+
+ void test() {
+ FILE *p = fopen("foo", "r");
+ } // warn: opened file is never closed
+
+ void test() {
+ FILE *p = fopen("foo", "r");
+ fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
+ fclose(p);
+ }
+
+ void test() {
+ FILE *p = fopen("foo", "r");
+
+ if (p)
+ fseek(p, 1, 3);
+ // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
+
+ fclose(p);
+ }
+
+ void test() {
+ FILE *p = fopen("foo", "r");
+ fclose(p);
+ fclose(p); // warn: already closed
+ }
+
+ void test() {
+ FILE *p = tmpfile();
+ ftell(p); // warn: stream pointer might be NULL
+ fclose(p);
+ }
+
+
+alpha.unix.cstring.BufferOverlap (C)
+""""""""""""""""""""""""""""""""""""
+Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy``.
+
+.. code-block:: c
+
+ void test() {
+ int a[4] = {0};
+ memcpy(a + 2, a + 1, 8); // warn
+ }
+
+alpha.unix.cstring.NotNullTerminated (C)
+""""""""""""""""""""""""""""""""""""""""
+Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``.
+
+.. code-block:: c
+
+ void test() {
+ int y = strlen((char *)&test); // warn
+ }
+
+alpha.unix.cstring.OutOfBounds (C)
+""""""""""""""""""""""""""""""""""
+Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``.
+
+
+.. code-block:: c
+
+ void test() {
+ int y = strlen((char *)&test); // warn
+ }
+
+alpha.nondeterminism.PointerSorting (C++)
+"""""""""""""""""""""""""""""""""""""""""
+Check for non-determinism caused by sorting of pointers.
+
+.. code-block:: c
+
+ void test() {
+ int a = 1, b = 2;
+ std::vector<int *> V = {&a, &b};
+ std::sort(V.begin(), V.end()); // warn
+ }
+
+
+Debug Checkers
+---------------
+
+.. _debug-checkers:
+
+
+debug
+^^^^^
+
+Checkers used for debugging the analyzer.
+:doc:`developer-docs/DebugChecks` page contains a detailed description.
+
+debug.AnalysisOrder
+"""""""""""""""""""
+Print callbacks that are called during analysis in order.
+
+debug.ConfigDumper
+""""""""""""""""""
+Dump config table.
+
+debug.DumpCFG Display
+"""""""""""""""""""""
+Control-Flow Graphs.
+
+debug.DumpCallGraph
+"""""""""""""""""""
+Display Call Graph.
+
+debug.DumpCalls
+"""""""""""""""
+Print calls as they are traversed by the engine.
+
+debug.DumpDominators
+""""""""""""""""""""
+Print the dominance tree for a given CFG.
+
+debug.DumpLiveVars
+""""""""""""""""""
+Print results of live variable analysis.
+
+debug.DumpTraversal
+"""""""""""""""""""
+Print branch conditions as they are traversed by the engine.
+
+debug.ExprInspection
+""""""""""""""""""""
+Check the analyzer's understanding of expressions.
+
+debug.Stats
+"""""""""""
+Emit warnings with analyzer statistics.
+
+debug.TaintTest
+"""""""""""""""
+Mark tainted symbols as such.
+
+debug.ViewCFG
+"""""""""""""
+View Control-Flow Graphs using GraphViz.
+
+debug.ViewCallGraph
+"""""""""""""""""""
+View Call Graph using GraphViz.
+
+debug.ViewExplodedGraph
+"""""""""""""""""""""""
+View Exploded Graphs using GraphViz.
+
diff --git a/docs/analyzer/checkers/callandmessage_example.c b/docs/analyzer/checkers/callandmessage_example.c
new file mode 100644
index 0000000000..7e14fbe464
--- /dev/null
+++ b/docs/analyzer/checkers/callandmessage_example.c
@@ -0,0 +1,66 @@
+//C
+void test() {
+ void (*foo)(void);
+ foo = 0;
+ foo(); // warn: function pointer is null
+ }
+
+ // C++
+ class C {
+ public:
+ void f();
+ };
+
+ void test() {
+ C *pc;
+ pc->f(); // warn: object pointer is uninitialized
+ }
+
+ // C++
+ class C {
+ public:
+ void f();
+ };
+
+ void test() {
+ C *pc = 0;
+ pc->f(); // warn: object pointer is null
+ }
+
+ // Objective-C
+ @interface MyClass : NSObject
+ @property (readwrite,assign) id x;
+ - (long double)longDoubleM;
+ @end
+
+ void test() {
+ MyClass *obj1;
+ long double ld1 = [obj1 longDoubleM];
+ // warn: receiver is uninitialized
+ }
+
+ // Objective-C
+ @interface MyClass : NSObject
+ @property (readwrite,assign) id x;
+ - (long double)longDoubleM;
+ @end
+
+ void test() {
+ MyClass *obj1;
+ id i = obj1.x; // warn: uninitialized object pointer
+ }
+
+ // Objective-C
+ @interface Subscriptable : NSObject
+ - (id)objectAtIndexedSubscript:(unsigned int)index;
+ @end
+
+ @interface MyClass : Subscriptable
+ @property (readwrite,assign) id x;
+ - (long double)longDoubleM;
+ @end
+
+ void test() {
+ MyClass *obj1;
+ id i = obj1[0]; // warn: uninitialized object pointer
+ }
diff --git a/docs/analyzer/checkers/dealloc_example.m b/docs/analyzer/checkers/dealloc_example.m
new file mode 100644
index 0000000000..ac51911aff
--- /dev/null
+++ b/docs/analyzer/checkers/dealloc_example.m
@@ -0,0 +1,49 @@
+
+
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@end
+
+@implementation MyObject // warn: lacks 'dealloc'
+@end
+
+@interface MyObject : NSObject {}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject // warn: does not send 'dealloc' to super
+- (void)dealloc {
+ self.myproperty = 0;
+}
+@end
+
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@property(retain) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty = _myproperty;
+ // warn: var was retained but wasn't released
+- (void)dealloc {
+ [super dealloc];
+}
+@end
+
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty = _myproperty;
+ // warn: var wasn't retained but was released
+- (void)dealloc {
+ [_myproperty release];
+ [super dealloc];
+}
+@end
+
diff --git a/docs/analyzer/checkers/dividezero_example.c b/docs/analyzer/checkers/dividezero_example.c
new file mode 100644
index 0000000000..00ffaac491
--- /dev/null
+++ b/docs/analyzer/checkers/dividezero_example.c
@@ -0,0 +1,9 @@
+void test(int z) {
+ if (z == 0)
+ int x = 1 / z; // warn
+}
+
+void test() {
+ int x = 1;
+ int y = x % 0; // warn
+}
diff --git a/docs/analyzer/checkers/mismatched_deallocator_example.cpp b/docs/analyzer/checkers/mismatched_deallocator_example.cpp
new file mode 100644
index 0000000000..2a4103240f
--- /dev/null
+++ b/docs/analyzer/checkers/mismatched_deallocator_example.cpp
@@ -0,0 +1,56 @@
+// C, C++
+void test() {
+ int *p = (int *)malloc(sizeof(int));
+ delete p; // warn
+}
+
+// C, C++
+void __attribute((ownership_returns(malloc))) *user_malloc(size_t);
+
+void test() {
+ int *p = (int *)user_malloc(sizeof(int));
+ delete p; // warn
+}
+
+// C, C++
+void test() {
+ int *p = new int;
+ free(p); // warn
+}
+
+// C, C++
+void test() {
+ int *p = new int[1];
+ realloc(p, sizeof(long)); // warn
+}
+
+// C, C++
+template <typename T>
+struct SimpleSmartPointer {
+ T *ptr;
+
+ explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
+ ~SimpleSmartPointer() {
+ delete ptr; // warn
+ }
+};
+
+void test() {
+ SimpleSmartPointer<int> a((int *)malloc(4));
+}
+
+// C++
+void test() {
+ int *p = (int *)operator new(0);
+ delete[] p; // warn
+}
+
+// Objective-C, C++
+void test(NSUInteger dataLength) {
+ int *p = new int;
+ NSData *d = [NSData dataWithBytesNoCopy:p
+ length:sizeof(int) freeWhenDone:1];
+ // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take
+ // ownership of memory allocated by 'new'
+}
+
diff --git a/docs/analyzer/checkers/newdelete_example.cpp b/docs/analyzer/checkers/newdelete_example.cpp
new file mode 100644
index 0000000000..b26ddcb3d9
--- /dev/null
+++ b/docs/analyzer/checkers/newdelete_example.cpp
@@ -0,0 +1,41 @@
+void f(int *p);
+
+void testUseMiddleArgAfterDelete(int *p) {
+ delete p;
+ f(p); // warn: use after free
+}
+
+class SomeClass {
+public:
+ void f();
+};
+
+void test() {
+ SomeClass *c = new SomeClass;
+ delete c;
+ c->f(); // warn: use after free
+}
+
+void test() {
+ int *p = (int *)__builtin_alloca(sizeof(int));
+ delete p; // warn: deleting memory allocated by alloca
+}
+
+void test() {
+ int *p = new int;
+ delete p;
+ delete p; // warn: attempt to free released
+}
+
+void test() {
+ int i;
+ delete &i; // warn: delete address of local
+}
+
+void test() {
+ int *p = new int[1];
+ delete[] (++p);
+ // warn: argument to 'delete[]' is offset by 4 bytes
+ // from the start of memory allocated by 'new[]'
+}
+
diff --git a/docs/analyzer/checkers/seckeychainapi_example.m b/docs/analyzer/checkers/seckeychainapi_example.m
new file mode 100644
index 0000000000..979a5d97c7
--- /dev/null
+++ b/docs/analyzer/checkers/seckeychainapi_example.m
@@ -0,0 +1,64 @@
+
+
+void test() {
+ unsigned int *ptr = 0;
+ UInt32 length;
+
+ SecKeychainItemFreeContent(ptr, &length);
+ // warn: trying to free data which has not been allocated
+}
+
+void test() {
+ unsigned int *ptr = 0;
+ UInt32 *length = 0;
+ void *outData;
+
+ OSStatus st =
+ SecKeychainItemCopyContent(2, ptr, ptr, length, outData);
+ // warn: data is not released
+}
+
+void test() {
+ unsigned int *ptr = 0;
+ UInt32 *length = 0;
+ void *outData;
+
+ OSStatus st =
+ SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
+
+ SecKeychainItemFreeContent(ptr, outData);
+ // warn: only call free if a non-NULL buffer was returned
+}
+
+void test() {
+ unsigned int *ptr = 0;
+ UInt32 *length = 0;
+ void *outData;
+
+ OSStatus st =
+ SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
+
+ st = SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
+ // warn: release data before another call to the allocator
+
+ if (st == noErr)
+ SecKeychainItemFreeContent(ptr, outData);
+}
+
+void test() {
+ SecKeychainItemRef itemRef = 0;
+ SecKeychainAttributeInfo *info = 0;
+ SecItemClass *itemClass = 0;
+ SecKeychainAttributeList *attrList = 0;
+ UInt32 *length = 0;
+ void *outData = 0;
+
+ OSStatus st =
+ SecKeychainItemCopyAttributesAndData(itemRef, info,
+ itemClass, &attrList,
+ length, &outData);
+
+ SecKeychainItemFreeContent(attrList, outData);
+ // warn: deallocator doesn't match the allocator
+}
+
diff --git a/docs/analyzer/checkers/unix_api_example.c b/docs/analyzer/checkers/unix_api_example.c
new file mode 100644
index 0000000000..66ed56fd86
--- /dev/null
+++ b/docs/analyzer/checkers/unix_api_example.c
@@ -0,0 +1,37 @@
+
+// Currently the check is performed for apple targets only.
+void test(const char *path) {
+ int fd = open(path, O_CREAT);
+ // warn: call to 'open' requires a third argument when the
+ // 'O_CREAT' flag is set
+}
+
+void f();
+
+void test() {
+ pthread_once_t pred = {0x30B1BCBA, {0}};
+ pthread_once(&pred, f);
+ // warn: call to 'pthread_once' uses the local variable
+}
+
+void test() {
+ void *p = malloc(0); // warn: allocation size of 0 bytes
+}
+
+void test() {
+ void *p = calloc(0, 42); // warn: allocation size of 0 bytes
+}
+
+void test() {
+ void *p = malloc(1);
+ p = realloc(p, 0); // warn: allocation size of 0 bytes
+}
+
+void test() {
+ void *p = alloca(0); // warn: allocation size of 0 bytes
+}
+
+void test() {
+ void *p = valloc(0); // warn: allocation size of 0 bytes
+}
+
diff --git a/docs/analyzer/checkers/unix_malloc_example.c b/docs/analyzer/checkers/unix_malloc_example.c
new file mode 100644
index 0000000000..68c5a4a8f1
--- /dev/null
+++ b/docs/analyzer/checkers/unix_malloc_example.c
@@ -0,0 +1,30 @@
+
+void test() {
+ int *p = malloc(1);
+ free(p);
+ free(p); // warn: attempt to free released memory
+}
+
+void test() {
+ int *p = malloc(sizeof(int));
+ free(p);
+ *p = 1; // warn: use after free
+}
+
+void test() {
+ int *p = malloc(1);
+ if (p)
+ return; // warn: memory is never released
+}
+
+void test() {
+ int a[] = { 1 };
+ free(a); // warn: argument is not allocated by malloc
+}
+
+void test() {
+ int *p = malloc(sizeof(char));
+ p = p - 1;
+ free(p); // warn: argument to free() is offset by -4 bytes
+}
+
diff --git a/docs/analyzer/developer-docs.rst b/docs/analyzer/developer-docs.rst
new file mode 100644
index 0000000000..a3d74a765f
--- /dev/null
+++ b/docs/analyzer/developer-docs.rst
@@ -0,0 +1,14 @@
+Developer Docs
+==============
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ developer-docs/DebugChecks
+ developer-docs/IPA
+ developer-docs/InitializerLists
+ developer-docs/nullability
+ developer-docs/RegionStore
+ \ No newline at end of file
diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/developer-docs/DebugChecks.rst
index bb2f37f339..56ce015d64 100644
--- a/docs/analyzer/DebugChecks.rst
+++ b/docs/analyzer/developer-docs/DebugChecks.rst
@@ -285,3 +285,10 @@ There is also an additional -analyzer-stats flag, which enables various
statistics within the analyzer engine. Note the Stats checker (which produces at
least one bug report per function) may actually change the values reported by
-analyzer-stats.
+
+Output testing checkers
+=======================
+
+- debug.ReportStmts reports a warning at **every** statement, making it a very
+ useful tool for testing thoroughly bug report construction and output
+ emission.
diff --git a/docs/analyzer/IPA.txt b/docs/analyzer/developer-docs/IPA.rst
index 3842075fcd..2e8fe37055 100644
--- a/docs/analyzer/IPA.txt
+++ b/docs/analyzer/developer-docs/IPA.rst
@@ -2,45 +2,46 @@ Inlining
========
There are several options that control which calls the analyzer will consider for
-inlining. The major one is -analyzer-config ipa:
+inlining. The major one is ``-analyzer-config ipa``:
- -analyzer-config ipa=none - All inlining is disabled. This is the only mode
- available in LLVM 3.1 and earlier and in Xcode 4.3 and earlier.
+* ``analyzer-config ipa=none`` - All inlining is disabled. This is the only mode
+ available in LLVM 3.1 and earlier and in Xcode 4.3 and earlier.
- -analyzer-config ipa=basic-inlining - Turns on inlining for C functions, C++
- static member functions, and blocks -- essentially, the calls that behave
- like simple C function calls. This is essentially the mode used in
- Xcode 4.4.
+* ``analyzer-config ipa=basic-inlining`` - Turns on inlining for C functions, C++
+ static member functions, and blocks -- essentially, the calls that behave
+ like simple C function calls. This is essentially the mode used in
+ Xcode 4.4.
- -analyzer-config ipa=inlining - Turns on inlining when we can confidently find
+* ``analyzer-config ipa=inlining`` - Turns on inlining when we can confidently find
the function/method body corresponding to the call. (C functions, static
functions, devirtualized C++ methods, Objective-C class methods, Objective-C
instance methods when ExprEngine is confident about the dynamic type of the
instance).
- -analyzer-config ipa=dynamic - Inline instance methods for which the type is
+* ``analyzer-config ipa=dynamic`` - Inline instance methods for which the type is
determined at runtime and we are not 100% sure that our type info is
correct. For virtual calls, inline the most plausible definition.
- -analyzer-config ipa=dynamic-bifurcate - Same as -analyzer-config ipa=dynamic,
+* ``analyzer-config ipa=dynamic-bifurcate`` - Same as -analyzer-config ipa=dynamic,
but the path is split. We inline on one branch and do not inline on the
other. This mode does not drop the coverage in cases when the parent class
has code that is only exercised when some of its methods are overridden.
-Currently, -analyzer-config ipa=dynamic-bifurcate is the default mode.
+Currently, ``-analyzer-config ipa=dynamic-bifurcate`` is the default mode.
-While -analyzer-config ipa determines in general how aggressively the analyzer
+While ``-analyzer-config ipa`` determines in general how aggressively the analyzer
will try to inline functions, several additional options control which types of
functions can inlined, in an all-or-nothing way. These options use the
analyzer's configuration table, so they are all specified as follows:
- -analyzer-config OPTION=VALUE
+ ``-analyzer-config OPTION=VALUE``
-### c++-inlining ###
+c++-inlining
+------------
This option controls which C++ member functions may be inlined.
- -analyzer-config c++-inlining=[none | methods | constructors | destructors]
+ ``-analyzer-config c++-inlining=[none | methods | constructors | destructors]``
Each of these modes implies that all the previous member function kinds will be
inlined as well; it doesn't make sense to inline destructors without inlining
@@ -55,11 +56,12 @@ destructors will not be inlined. Additionally, no C++ member functions will be
inlined under -analyzer-config ipa=none or -analyzer-config ipa=basic-inlining,
regardless of the setting of the c++-inlining mode.
-### c++-template-inlining ###
+c++-template-inlining
+^^^^^^^^^^^^^^^^^^^^^
This option controls whether C++ templated functions may be inlined.
- -analyzer-config c++-template-inlining=[true | false]
+ ``-analyzer-config c++-template-inlining=[true | false]``
Currently, template functions are considered for inlining by default.
@@ -68,13 +70,14 @@ of false positives, either by considering paths that the caller considers
impossible (by some unstated precondition), or by inlining some but not all
of a deep implementation of a function.
-### c++-stdlib-inlining ###
+c++-stdlib-inlining
+^^^^^^^^^^^^^^^^^^^
This option controls whether functions from the C++ standard library, including
methods of the container classes in the Standard Template Library, should be
considered for inlining.
- -analyzer-config c++-stdlib-inlining=[true | false]
+ ``-analyzer-config c++-stdlib-inlining=[true | false]``
Currently, C++ standard library functions are considered for inlining by
default.
@@ -85,12 +88,13 @@ positive due to poor modeling of the STL leads to a poor user experience, since
most users would not be comfortable adding assertions to system headers in order
to silence analyzer warnings.
-### c++-container-inlining ###
+c++-container-inlining
+^^^^^^^^^^^^^^^^^^^^^^
This option controls whether constructors and destructors of "container" types
should be considered for inlining.
- -analyzer-config c++-container-inlining=[true | false]
+ ``-analyzer-config c++-container-inlining=[true | false]``
Currently, these constructors and destructors are NOT considered for inlining
by default.
@@ -101,9 +105,12 @@ with the latter specified in the C++11 standard. The analyzer currently does a
fairly poor job of modeling certain data structure invariants of container-like
objects. For example, these three expressions should be equivalent:
- std::distance(c.begin(), c.end()) == 0
- c.begin() == c.end()
- c.empty())
+
+.. code-block:: cpp
+
+ std::distance(c.begin(), c.end()) == 0
+ c.begin() == c.end()
+ c.empty()
Many of these issues are avoided if containers always have unknown, symbolic
state, which is what happens when their constructors are treated as opaque.
@@ -112,7 +119,7 @@ inlining, or choose to model them directly using checkers instead.
Basics of Implementation
------------------------
+------------------------
The low-level mechanism of inlining a function is handled in
ExprEngine::inlineCall and ExprEngine::processCallExit.
@@ -144,7 +151,7 @@ reasonable steps:
onto the work list, so that evaluation of the caller can continue.
Retry Without Inlining
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
In some cases, we would like to retry analysis without inlining a particular
call.
@@ -159,7 +166,7 @@ ReplayWithoutInlining bit added to it (ExprEngine::replayWithoutInlining). The
path is then re-analyzed from that point without inlining that particular call.
Deciding When to Inline
------------------------
+^^^^^^^^^^^^^^^^^^^^^^^
In general, the analyzer attempts to inline as much as possible, since it
provides a better summary of what actually happens in the program. There are
@@ -202,7 +209,7 @@ some cases, however, where the analyzer chooses not to inline:
Dynamic Calls and Devirtualization
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"Dynamic" calls are those that are resolved at runtime, such as C++ virtual
method calls and Objective-C message sends. Due to the path-sensitive nature of
@@ -214,7 +221,8 @@ method would actually be called at runtime. This is possible when the type
information is constrained enough for a simulated C++/Objective-C object that
the analyzer can make such a decision.
- == DynamicTypeInfo ==
+DynamicTypeInfo
+^^^^^^^^^^^^^^^
As the analyzer analyzes a path, it may accrue information to refine the
knowledge about the type of an object. This can then be used to make better
@@ -241,7 +249,8 @@ information for a region.
off, but sometimes the information provided by casts can be useful.
- == RuntimeDefinition ==
+RuntimeDefinition
+^^^^^^^^^^^^^^^^^
The basis of devirtualization is CallEvent's getRuntimeDefinition() method,
which returns a RuntimeDefinition object. When asked to provide a definition,
@@ -258,7 +267,8 @@ corresponding to the object being called (i.e., the "receiver" in Objective-C
parlance), which ExprEngine uses to decide whether or not the call should be
inlined.
- == Inlining Dynamic Calls ==
+Inlining Dynamic Calls
+^^^^^^^^^^^^^^^^^^^^^^
The -analyzer-config ipa option has five different modes: none, basic-inlining,
inlining, dynamic, and dynamic-bifurcate. Under -analyzer-config ipa=dynamic,
@@ -282,9 +292,9 @@ can be safely devirtualized.
Bifurcation
------------
+^^^^^^^^^^^
-ExprEngine::BifurcateCall implements the -analyzer-config ipa=dynamic-bifurcate
+ExprEngine::BifurcateCall implements the ``-analyzer-config ipa=dynamic-bifurcate``
mode.
When a call is made on an object with imprecise dynamic type information
@@ -294,14 +304,14 @@ RuntimeDefinition object) with a path-sensitive "mode" in the ProgramState.
Currently, there are 2 modes:
- DynamicDispatchModeInlined - Models the case where the dynamic type information
+* ``DynamicDispatchModeInlined`` - Models the case where the dynamic type information
of the receiver (MemoryRegion) is assumed to be perfectly constrained so
that a given definition of a method is expected to be the code actually
called. When this mode is set, ExprEngine uses the Decl from
RuntimeDefinition to inline any dynamically dispatched call sent to this
receiver because the function definition is considered to be fully resolved.
- DynamicDispatchModeConservative - Models the case where the dynamic type
+* ``DynamicDispatchModeConservative`` - Models the case where the dynamic type
information is assumed to be incorrect, for example, implies that the method
definition is overridden in a subclass. In such cases, ExprEngine does not
inline the methods sent to the receiver (MemoryRegion), even if a candidate
@@ -319,7 +329,7 @@ performance hit and the possibility of false positives on the path where the
conservative mode is used.
Objective-C Message Heuristics
-------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ExprEngine relies on a set of heuristics to partition the set of Objective-C
method calls into those that require bifurcation and those that do not. Below
@@ -340,7 +350,7 @@ are the cases when the DynamicTypeInfo of the object is considered precise
receiver's class or by any superclasses.
C++ Caveats
---------------------
+^^^^^^^^^^^
C++11 [class.cdtor]p4 describes how the vtable of an object is modified as it is
being constructed or destructed; that is, the type of the object depends on
@@ -349,21 +359,21 @@ DynamicTypeInfo in the DynamicTypePropagation checker.
There are several limitations in the current implementation:
-- Temporaries are poorly modeled right now because we're not confident in the
+* Temporaries are poorly modeled right now because we're not confident in the
placement of their destructors in the CFG. We currently won't inline their
constructors unless the destructor is trivial, and don't process their
destructors at all, not even to invalidate the region.
-- 'new' is poorly modeled due to some nasty CFG/design issues. This is tracked
+* 'new' is poorly modeled due to some nasty CFG/design issues. This is tracked
in PR12014. 'delete' is not modeled at all.
-- Arrays of objects are modeled very poorly right now. ExprEngine currently
+* Arrays of objects are modeled very poorly right now. ExprEngine currently
only simulates the first constructor and first destructor. Because of this,
ExprEngine does not inline any constructors or destructors for arrays.
CallEvent
-=========
+^^^^^^^^^
A CallEvent represents a specific call to a function, method, or other body of
code. It is path-sensitive, containing both the current state (ProgramStateRef)
diff --git a/docs/analyzer/DesignDiscussions/InitializerLists.rst b/docs/analyzer/developer-docs/InitializerLists.rst
index af41e4ec8f..c9dc7a0489 100644
--- a/docs/analyzer/DesignDiscussions/InitializerLists.rst
+++ b/docs/analyzer/developer-docs/InitializerLists.rst
@@ -1,3 +1,6 @@
+================
+Initializer List
+================
This discussion took place in https://reviews.llvm.org/D35216
"Escape symbols when creating std::initializer_list".
@@ -20,11 +23,11 @@ passed into initializer list expressions to immediately escape.
This fix is overly conservative though. So i did a bit of investigation as to
how model std::initializer_list better.
-According to the standard, std::initializer_list<T> is an object that has
-methods begin(), end(), and size(), where begin() returns a pointer to continuous
-array of size() objects of type T, and end() is equal to begin() plus size().
+According to the standard, ``std::initializer_list<T>`` is an object that has
+methods ``begin(), end(), and size()``, where ``begin()`` returns a pointer to continuous
+array of ``size()`` objects of type T, and end() is equal to begin() plus size().
The standard does hint that it should be possible to implement
-std::initializer_list<T> as a pair of pointers, or as a pointer and a size
+``std::initializer_list<T>`` as a pair of pointers, or as a pointer and a size
integer, however specific fields that the object would contain are an
implementation detail.
@@ -33,21 +36,21 @@ Or, at least, it should be possible to explain to the analyzer that the list
somehow "takes hold" of the values put into it. Initializer lists can also be
copied, which is a separate story that i'm not trying to address here.
-The obvious approach to modeling std::initializer_list in a checker would be to
+The obvious approach to modeling ``std::initializer_list`` in a checker would be to
construct a SymbolMetadata for the memory region of the initializer list object,
-which would be of type T* and represent begin(), so we'd trivially model begin()
+which would be of type ``T*`` and represent ``begin()``, so we'd trivially model ``begin()``
as a function that returns this symbol. The array pointed to by that symbol
-would be bindLoc()ed to contain the list's contents (probably as a CompoundVal
+would be ``bindLoc()``ed to contain the list's contents (probably as a ``CompoundVal``
to produce less bindings in the store). Extent of this array would represent
-size() and would be equal to the length of the list as written.
+``size()`` and would be equal to the length of the list as written.
So this sounds good, however apparently it does nothing to address our false
-positives: when the list escapes, our RegionStoreManager is not magically
+positives: when the list escapes, our ``RegionStoreManager`` is not magically
guessing that the metadata symbol attached to it, together with its contents,
should also escape. In fact, it's impossible to trigger a pointer escape from
within the checker.
-Approach (1): If only we enabled ProgramState::bindLoc(..., notifyChanges=true)
+Approach (1): If only we enabled ``ProgramState::bindLoc(..., notifyChanges=true)``
to cause pointer escapes (not only region changes) (which sounds like the right
thing to do anyway) such checker would be able to solve the false positives by
triggering escapes when binding list elements to the list. However, it'd be as
@@ -71,7 +74,7 @@ to escape. This puts a stress on the checkers, but with a smart data map it
wouldn't be a problem.
Approach (4): We could allow checkers to trigger pointer escapes in arbitrary
-moments. If we allow doing this within checkPointerEscape callback itself, we
+moments. If we allow doing this within ``checkPointerEscape`` callback itself, we
would be able to express facts like "when this region escapes, that metadata
symbol attached to it should also escape". This sounds like an ultimate freedom,
with maximum stress on the checkers - still not too much stress when we have
@@ -84,11 +87,10 @@ performance overhead, and clarity seems nice.
At this point, I am a bit wondering about two questions.
-- When should something belong to a checker and when should something belong
-to the engine? Sometimes we model library aspects in the engine and model
-language constructs in checkers.
-- What is the checker programming model that we are aiming for? Maximum
-freedom or more easy checker development?
+* When should something belong to a checker and when should something belong to the engine?
+ Sometimes we model library aspects in the engine and model language constructs in checkers.
+
+* What is the checker programming model that we are aiming for? Maximum freedom or more easy checker development?
I think if we aim for maximum freedom, we do not need to worry about the
potential stress on checkers, and we can introduce abstractions to mitigate that
@@ -100,36 +102,37 @@ of complicating the API.
Right now I have no preference or objections between the alternatives but there
are some random thoughts:
-- Maybe it would be great to have a guideline how to evolve the analyzer and
-follow it, so it can help us to decide in similar situations
-- I do care about performance in this case. The reason is that we have a
-limited performance budget. And I think we should not expect most of the checker
-writers to add modeling of language constructs. So, in my opinion, it is ok to
-have less nice/more verbose API for language modeling if we can have better
-performance this way, since it only needs to be done once, and is done by the
-framework developers.
+* Maybe it would be great to have a guideline how to evolve the analyzer and
+ follow it, so it can help us to decide in similar situations
+
+* I do care about performance in this case. The reason is that we have a
+ limited performance budget. And I think we should not expect most of the checker
+ writers to add modeling of language constructs. So, in my opinion, it is ok to
+ have less nice/more verbose API for language modeling if we can have better
+ performance this way, since it only needs to be done once, and is done by the
+ framework developers.
**Artem:** These are some great questions, i guess it'd be better to discuss
them more openly. As a quick dump of my current mood:
-- To me it seems obvious that we need to aim for a checker API that is both
-simple and powerful. This can probably by keeping the API as powerful as
-necessary while providing a layer of simple ready-made solutions on top of it.
-Probably a few reusable components for assembling checkers. And this layer
-should ideally be pleasant enough to work with, so that people would prefer to
-extend it when something is lacking, instead of falling back to the complex
-omnipotent API. I'm thinking of AST matchers vs. AST visitors as a roughly
-similar situation: matchers are not omnipotent, but they're so nice.
-
-- Separation between core and checkers is usually quite strange. Once we have
-shared state traits, i generally wouldn't mind having region store or range
-constraint manager as checkers (though it's probably not worth it to transform
-them - just a mood). The main thing to avoid here would be the situation when
-the checker overwrites stuff written by the core because it thinks it has a
-better idea what's going on, so the core should provide a good default behavior.
-
-- Yeah, i totally care about performance as well, and if i try to implement
-approach, i'd make sure it's good.
+* To me it seems obvious that we need to aim for a checker API that is both
+ simple and powerful. This can probably by keeping the API as powerful as
+ necessary while providing a layer of simple ready-made solutions on top of it.
+ Probably a few reusable components for assembling checkers. And this layer
+ should ideally be pleasant enough to work with, so that people would prefer to
+ extend it when something is lacking, instead of falling back to the complex
+ omnipotent API. I'm thinking of AST matchers vs. AST visitors as a roughly
+ similar situation: matchers are not omnipotent, but they're so nice.
+
+* Separation between core and checkers is usually quite strange. Once we have
+ shared state traits, i generally wouldn't mind having region store or range
+ constraint manager as checkers (though it's probably not worth it to transform
+ them - just a mood). The main thing to avoid here would be the situation when
+ the checker overwrites stuff written by the core because it thinks it has a
+ better idea what's going on, so the core should provide a good default behavior.
+
+* Yeah, i totally care about performance as well, and if i try to implement
+ approach, i'd make sure it's good.
**Artem:**
@@ -145,7 +148,7 @@ value in different moments of time, but at most one of them represents the
actual metadata value. So we'd be escaping more stuff than necessary.
If only we had "ghost fields"
-(http://lists.llvm.org/pipermail/cfe-dev/2016-May/049000.html), it would have
+(https://lists.llvm.org/pipermail/cfe-dev/2016-May/049000.html), it would have
been much easier, because the ghost field would only contain the actual
metadata, and the Store would always know about it. This example adds to my
belief that ghost fields are exactly what we need for most C++ checkers.
@@ -159,7 +162,7 @@ with different identifiers. This wouldn't specify how the memory is reachable,
but it would allow for transfer functions to get at those regions and it would
allow for invalidation.
-For std::initializer_list this reachable region would the region for the backing
+For ``std::initializer_list`` this reachable region would the region for the backing
array and the transfer functions for begin() and end() yield the beginning and
end element regions for it.
@@ -185,7 +188,7 @@ invalidation for free.
**Artem:**
-> In this case, I would be fine with some sort of AbstractStorageMemoryRegion
+> In this case, I would be fine with some sort of ``AbstractStorageMemoryRegion``
> that meant "here is a memory region and somewhere reachable from here exists
> another region of type T". Or even multiple regions with different
> identifiers. This wouldn't specify how the memory is reachable, but it would
@@ -196,7 +199,7 @@ Yeah, this is what we can easily implement now as a
symbolic-region-based-on-a-metadata-symbol (though we can make a new region
class for that if we eg. want it typed). The problem is that the relation
between such storage region and its parent object region is essentially
-immaterial, similarly to the relation between SymbolRegionValue and its parent
+immaterial, similarly to the relation between ``SymbolRegionValue`` and its parent
region. Region contents are mutable: today the abstract storage is reachable
from its parent object, tomorrow it's not, and maybe something else becomes
reachable, something that isn't even abstract. So the parent region for the
@@ -213,28 +216,31 @@ change the data after the object is constructed - so this region's contents are
essentially immutable. For the future, i feel as if it is a dead end.
I'd like to consider another funny example. Suppose we're trying to model
-std::unique_ptr. Consider::
-
- void bar(const std::unique_ptr<int> &x);
-
- void foo(std::unique_ptr<int> &x) {
- int *a = x.get(); // (a, 0, direct): &AbstractStorageRegion
- *a = 1; // (AbstractStorageRegion, 0, direct): 1 S32b
- int *b = new int;
- *b = 2; // (SymRegion{conj_$0<int *>}, 0 ,direct): 2 S32b
- x.reset(b); // Checker map: x -> SymRegion{conj_$0<int *>}
- bar(x); // 'a' doesn't escape (the pointer was unique), 'b' does.
- clang_analyzer_eval(*a == 1); // Making this true is up to the checker.
- clang_analyzer_eval(*b == 2); // Making this unknown is up to the checker.
- }
-
-The checker doesn't totally need to ensure that *a == 1 passes - even though the
-pointer was unique, it could theoretically have .get()-ed above and the code
+
+.. code-block:: cpp
+
+ std::unique_ptr. Consider::
+
+ void bar(const std::unique_ptr<int> &x);
+
+ void foo(std::unique_ptr<int> &x) {
+ int *a = x.get(); // (a, 0, direct): &AbstractStorageRegion
+ *a = 1; // (AbstractStorageRegion, 0, direct): 1 S32b
+ int *b = new int;
+ *b = 2; // (SymRegion{conj_$0<int *>}, 0 ,direct): 2 S32b
+ x.reset(b); // Checker map: x -> SymRegion{conj_$0<int *>}
+ bar(x); // 'a' doesn't escape (the pointer was unique), 'b' does.
+ clang_analyzer_eval(*a == 1); // Making this true is up to the checker.
+ clang_analyzer_eval(*b == 2); // Making this unknown is up to the checker.
+ }
+
+The checker doesn't totally need to ensure that ``*a == 1`` passes - even though the
+pointer was unique, it could theoretically have ``.get()``-ed above and the code
could of course break the uniqueness invariant (though we'd probably want it).
-The checker can say that "even if *a did escape, it was not because it was
+The checker can say that "even if ``*a`` did escape, it was not because it was
stuffed directly into bar()".
-The checker's direct responsibility, however, is to solve the *b == 2 thing
+The checker's direct responsibility, however, is to solve the ``*b == 2`` thing
(which is in fact the problem we're dealing with in this patch - escaping the
storage region of the object).
@@ -293,7 +299,7 @@ FunctionDecl's body in a body farm to have a local variable, even if such
variable doesn't actually exist, even if it cannot be seen from outside the
function call. I'm not seeing immediate practical difference between "it does
actually exist" and "it doesn't actually exist, just a handy abstraction".
-Similarly, i think it's fine if we have a CXXRecordDecl with
+Similarly, i think it's fine if we have a ``CXXRecordDecl`` with
implementation-defined contents, and try to farm up a member variable as a handy
abstraction (we don't even need to know its name or offset, only that it's there
somewhere).
@@ -303,18 +309,18 @@ somewhere).
We've discussed it in person with Devin, and he provided more points to think
about:
-- If the initializer list consists of non-POD data, constructors of list's
-objects need to take the sub-region of the list's region as this-region In the
-current (v2) version of this patch, these objects are constructed elsewhere and
-then trivial-copied into the list's metadata pointer region, which may be
-incorrect. This is our overall problem with C++ constructors, which manifests in
-this case as well. Additionally, objects would need to be constructed in the
-analyzer's core, which would not be able to predict that it needs to take a
-checker-specific region as this-region, which makes it harder, though it might
-be mitigated by sharing the checker state traits.
-
-- Because "ghost variables" are not material to the user, we need to somehow
-make super sure that they don't make it into the diagnostic messages.
+* If the initializer list consists of non-POD data, constructors of list's
+ objects need to take the sub-region of the list's region as this-region In the
+ current (v2) version of this patch, these objects are constructed elsewhere and
+ then trivial-copied into the list's metadata pointer region, which may be
+ incorrect. This is our overall problem with C++ constructors, which manifests in
+ this case as well. Additionally, objects would need to be constructed in the
+ analyzer's core, which would not be able to predict that it needs to take a
+ checker-specific region as this-region, which makes it harder, though it might
+ be mitigated by sharing the checker state traits.
+
+* Because "ghost variables" are not material to the user, we need to somehow
+ make super sure that they don't make it into the diagnostic messages.
So, because this needs further digging into overall C++ support and rises too
many questions, i'm delaying a better approach to this problem and will fall
diff --git a/docs/analyzer/RegionStore.txt b/docs/analyzer/developer-docs/RegionStore.rst
index ef994b6401..c963e5b720 100644
--- a/docs/analyzer/RegionStore.txt
+++ b/docs/analyzer/developer-docs/RegionStore.rst
@@ -1,11 +1,14 @@
+============
+Region Store
+============
The analyzer "Store" represents the contents of memory regions. It is an opaque
-functional data structure stored in each ProgramState; the only class that can
-modify the store is its associated StoreManager.
+functional data structure stored in each ``ProgramState``; the only class that
+can modify the store is its associated StoreManager.
Currently (Feb. 2013), the only StoreManager implementation being used is
-RegionStoreManager. This store records bindings to memory regions using a "base
-region + offset" key. (This allows `*p` and `p[0]` to map to the same location,
-among other benefits.)
+``RegionStoreManager``. This store records bindings to memory regions using a
+"base region + offset" key. (This allows ``*p`` and ``p[0]`` to map to the same
+location, among other benefits.)
Regions are grouped into "clusters", which roughly correspond to "regions with
the same base region". This allows certain operations to be more efficient,
@@ -14,50 +17,55 @@ such as invalidation.
Regions that do not have a known offset use a special "symbolic" offset. These
keys store both the original region, and the "concrete offset region" -- the
last region whose offset is entirely concrete. (For example, in the expression
-`foo.bar[1][i].baz`, the concrete offset region is the array `foo.bar[1]`,
-since that has a known offset from the start of the top-level `foo` struct.)
+``foo.bar[1][i].baz``, the concrete offset region is the array ``foo.bar[1]``,
+since that has a known offset from the start of the top-level ``foo`` struct.)
Binding Invalidation
-====================
+--------------------
Supporting both concrete and symbolic offsets makes things a bit tricky. Here's
an example:
- foo[0] = 0;
- foo[1] = 1;
- foo[i] = i;
+.. code-block:: cpp
-After the third assignment, nothing can be said about the value of `foo[0]`,
-because `foo[i]` may have overwritten it! Thus, *binding to a region with a
+ foo[0] = 0;
+ foo[1] = 1;
+ foo[i] = i;
+
+After the third assignment, nothing can be said about the value of ``foo[0]``,
+because ``foo[i]`` may have overwritten it! Thus, *binding to a region with a
symbolic offset invalidates the entire concrete offset region.* We know
-`foo[i]` is somewhere within `foo`, so we don't have to invalidate anything
-else, but we do have to be conservative about all other bindings within `foo`.
+``foo[i]`` is somewhere within ``foo``, so we don't have to invalidate
+anything else, but we do have to be conservative about all other bindings within
+``foo``.
Continuing the example:
- foo[i] = i;
- foo[0] = 0;
+.. code-block:: cpp
+
+ foo[i] = i;
+ foo[0] = 0;
-After this latest assignment, nothing can be said about the value of `foo[i]`,
-because `foo[0]` may have overwritten it! *Binding to a region R with a
+After this latest assignment, nothing can be said about the value of ``foo[i]``,
+because ``foo[0]`` may have overwritten it! *Binding to a region R with a
concrete offset invalidates any symbolic offset bindings whose concrete offset
-region is a super-region **or** sub-region of R.* All we know about `foo[i]` is
-that it is somewhere within `foo`, so changing *anything* within `foo` might
-change `foo[i]`, and changing *all* of `foo` (or its base region) will
-*definitely* change `foo[i]`.
+region is a super-region **or** sub-region of R.* All we know about ``foo[i]``
+is that it is somewhere within ``foo``, so changing *anything* within ``foo``
+might change ``foo[i]``, and changing *all* of ``foo`` (or its base region) will
+*definitely* change ``foo[i]``.
-This logic could be improved by using the current constraints on `i`, at the
+This logic could be improved by using the current constraints on ``i``, at the
cost of speed. The latter case could also be improved by matching region kinds,
-i.e. changing `foo[0].a` is unlikely to affect `foo[i].b`, no matter what `i`
-is.
+i.e. changing ``foo[0].a`` is unlikely to affect ``foo[i].b``, no matter what
+``i`` is.
-For more detail, read through RegionStoreManager::removeSubRegionBindings in
+For more detail, read through ``RegionStoreManager::removeSubRegionBindings`` in
RegionStore.cpp.
ObjCIvarRegions
-===============
+---------------
Objective-C instance variables require a bit of special handling. Like struct
fields, they are not base regions, and when their parent object region is
@@ -76,7 +84,7 @@ offsets start from the base region!
Region Invalidation
-===================
+-------------------
Unlike binding invalidation, region invalidation occurs when the entire
contents of a region may have changed---say, because it has been passed to a
@@ -89,8 +97,8 @@ arithmetic.
Region invalidation typically does even more than this, however. Because it
usually represents the complete escape of a region from the analyzer's model,
its *contents* must also be transitively invalidated. (For example, if a region
-'p' of type 'int **' is invalidated, the contents of '*p' and '**p' may have
-changed as well.) The algorithm that traverses this transitive closure of
+``p`` of type ``int **`` is invalidated, the contents of ``*p`` and ``**p`` may
+have changed as well.) The algorithm that traverses this transitive closure of
accessible regions is known as ClusterAnalysis, and is also used for finding
all live bindings in the store (in order to throw away the dead ones). The name
"ClusterAnalysis" predates the cluster-based organization of bindings, but
@@ -100,7 +108,7 @@ model of program behavior.
Default Bindings
-================
+----------------
Most bindings in RegionStore are simple scalar values -- integers and pointers.
These are known as "Direct" bindings. However, RegionStore supports a second
@@ -115,6 +123,8 @@ the base region is reached, at which point the RegionStore will pick an
appropriate default value for the region (usually a symbolic value, but
sometimes zero, for static data, or "uninitialized", for stack variables).
+.. code-block:: cpp
+
int manyInts[10];
manyInts[1] = 42; // Creates a Direct binding for manyInts[1].
print(manyInts[1]); // Retrieves the Direct binding for manyInts[1];
@@ -132,7 +142,7 @@ for the sub-aggregate at offset 0.
Lazy Bindings (LazyCompoundVal)
-===============================
+-------------------------------
RegionStore implements an optimization for copying aggregates (structs and
arrays) called "lazy bindings", implemented using a special SVal called
@@ -158,14 +168,16 @@ LazyCompoundVal region, and look up *that* region in the previous store.
Here's a concrete example:
- CGPoint p;
- p.x = 42; // A Direct binding is made to the FieldRegion 'p.x'.
- CGPoint p2 = p; // A LazyCompoundVal is created for 'p', along with a
- // snapshot of the current store state. This value is then
- // used as a Default binding for the VarRegion 'p2'.
- return p2.x; // The binding for FieldRegion 'p2.x' is requested.
- // There is no Direct binding, so we look for a Default
- // binding to 'p2' and find the LCV.
- // Because it's a LCV, we look at our requested region
- // and see that it's the '.x' field. We ask for the value
- // of 'p.x' within the snapshot, and get back 42.
+.. code-block:: cpp
+
+ CGPoint p;
+ p.x = 42; // A Direct binding is made to the FieldRegion 'p.x'.
+ CGPoint p2 = p; // A LazyCompoundVal is created for 'p', along with a
+ // snapshot of the current store state. This value is then
+ // used as a Default binding for the VarRegion 'p2'.
+ return p2.x; // The binding for FieldRegion 'p2.x' is requested.
+ // There is no Direct binding, so we look for a Default
+ // binding to 'p2' and find the LCV.
+ // Because it's a LCV, we look at our requested region
+ // and see that it's the '.x' field. We ask for the value
+ // of 'p.x' within the snapshot, and get back 42.
diff --git a/docs/analyzer/nullability.rst b/docs/analyzer/developer-docs/nullability.rst
index 93909d0f25..be6f473dbd 100644
--- a/docs/analyzer/nullability.rst
+++ b/docs/analyzer/developer-docs/nullability.rst
@@ -1,6 +1,6 @@
-============
+==================
Nullability Checks
-============
+==================
This document is a high level description of the nullablility checks.
These checks intended to use the annotations that is described in this
@@ -8,85 +8,100 @@ RFC: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-March/041798.html.
Let's consider the following 2 categories:
-1) nullable
-============
+**1) nullable**
-If a pointer 'p' has a nullable annotation and no explicit null check or assert, we should warn in the following cases:
-- 'p' gets implicitly converted into nonnull pointer, for example, we are passing it to a function that takes a nonnull parameter.
-- 'p' gets dereferenced
+If a pointer ``p`` has a nullable annotation and no explicit null check or assert, we should warn in the following cases:
+
+* ``p`` gets implicitly converted into nonnull pointer, for example, we are passing it to a function that takes a nonnull parameter.
+* ``p`` gets dereferenced
Taking a branch on nullable pointers are the same like taking branch on null unspecified pointers.
-Explicit cast from nullable to nonnul::
+Explicit cast from nullable to nonnul:
+
+.. code-block:: cpp
- __nullable id foo;
- id bar = foo;
- takesNonNull((_nonnull) bar); <— should not warn here (backward compatibility hack)
- anotherTakesNonNull(bar); <— would be great to warn here, but not necessary(*)
+ __nullable id foo;
+ id bar = foo;
+ takesNonNull((_nonnull) bar); // should not warn here (backward compatibility hack)
+ anotherTakesNonNull(bar); // would be great to warn here, but not necessary(*)
Because bar corresponds to the same symbol all the time it is not easy to implement the checker that way the cast only suppress the first call but not the second. For this reason in the first implementation after a contradictory cast happens, I will treat bar as nullable unspecified, this way all of the warnings will be suppressed. Treating the symbol as nullable unspecified also has an advantage that in case the takesNonNull function body is being inlined, the will be no warning, when the symbol is dereferenced. In case I have time after the initial version I might spend additional time to try to find a more sophisticated solution, in which we would produce the second warning (*).
-2) nonnull
-============
-
-- Dereferencing a nonnull, or sending message to it is ok.
-- Converting nonnull to nullable is Ok.
-- When there is an explicit cast from nonnull to nullable I will trust the cast (it is probable there for a reason, because this cast does not suppress any warnings or errors).
-- But what should we do about null checks?::
-
- __nonnull id takesNonnull(__nonnull id x) {
- if (x == nil) {
- // Defensive backward compatible code:
- ....
- return nil; <- Should the analyzer cover this piece of code? Should we require the cast (__nonnull)nil?
- }
- ....
- }
+**2) nonnull**
+
+* Dereferencing a nonnull, or sending message to it is ok.
+* Converting nonnull to nullable is Ok.
+* When there is an explicit cast from nonnull to nullable I will trust the cast (it is probable there for a reason, because this cast does not suppress any warnings or errors).
+* But what should we do about null checks?:
+
+.. code-block:: cpp
+
+ __nonnull id takesNonnull(__nonnull id x) {
+ if (x == nil) {
+ // Defensive backward compatible code:
+ ....
+ return nil; // Should the analyzer cover this piece of code? Should we require the cast (__nonnull)nil?
+ }
+ ....
+ }
There are these directions:
-- We can either take the branch; this way the branch is analyzed
- - Should we not warn about any nullability issues in that branch? Probably not, it is ok to break the nullability postconditions when the nullability preconditions are violated.
-- We can assume that these pointers are not null and we lose coverage with the analyzer. (This can be implemented either in constraint solver or in the checker itself.)
+
+* We can either take the branch; this way the branch is analyzed
+* Should we not warn about any nullability issues in that branch? Probably not, it is ok to break the nullability postconditions when the nullability preconditions are violated.
+* We can assume that these pointers are not null and we lose coverage with the analyzer. (This can be implemented either in constraint solver or in the checker itself.)
Other Issues to keep in mind/take care of:
-Messaging:
-- Sending a message to a nullable pointer
- - Even though the method might return a nonnull pointer, when it was sent to a nullable pointer the return type will be nullable.
- - The result is nullable unless the receiver is known to be non null.
-- Sending a message to a unspecified or nonnull pointer
- - If the pointer is not assumed to be nil, we should be optimistic and use the nullability implied by the method.
- - This will not happen automatically, since the AST will have null unspecified in this case.
+
+* Messaging:
+
+ * Sending a message to a nullable pointer
+
+ * Even though the method might return a nonnull pointer, when it was sent to a nullable pointer the return type will be nullable.
+ * The result is nullable unless the receiver is known to be non null.
+
+ * Sending a message to a unspecified or nonnull pointer
+
+ * If the pointer is not assumed to be nil, we should be optimistic and use the nullability implied by the method.
+
+ * This will not happen automatically, since the AST will have null unspecified in this case.
Inlining
-============
+--------
-A symbol may need to be treated differently inside an inlined body. For example, consider these conversions from nonnull to nullable in presence of inlining::
+A symbol may need to be treated differently inside an inlined body. For example, consider these conversions from nonnull to nullable in presence of inlining:
- id obj = getNonnull();
- takesNullable(obj);
- takesNonnull(obj);
-
- void takesNullable(nullable id obj) {
- obj->ivar // we should assume obj is nullable and warn here
- }
+.. code-block:: cpp
+
+ id obj = getNonnull();
+ takesNullable(obj);
+ takesNonnull(obj);
+
+ void takesNullable(nullable id obj) {
+ obj->ivar // we should assume obj is nullable and warn here
+ }
With no special treatment, when the takesNullable is inlined the analyzer will not warn when the obj symbol is dereferenced. One solution for this is to reanalyze takesNullable as a top level function to get possible violations. The alternative method, deducing nullability information from the arguments after inlining is not robust enough (for example there might be more parameters with different nullability, but in the given path the two parameters might end up being the same symbol or there can be nested functions that take different view of the nullability of the same symbol). So the symbol will remain nonnull to avoid false positives but the functions that takes nullable parameters will be analyzed separately as well without inlining.
Annotations on multi level pointers
-============
+-----------------------------------
+
+Tracking multiple levels of annotations for pointers pointing to pointers would make the checker more complicated, because this way a vector of nullability qualifiers would be needed to be tracked for each symbol. This is not a big caveat, since once the top level pointer is dereferenced, the symvol for the inner pointer will have the nullability information. The lack of multi level annotation tracking only observable, when multiple levels of pointers are passed to a function which has a parameter with multiple levels of annotations. So for now the checker support the top level nullability qualifiers only.:
-Tracking multiple levels of annotations for pointers pointing to pointers would make the checker more complicated, because this way a vector of nullability qualifiers would be needed to be tracked for each symbol. This is not a big caveat, since once the top level pointer is dereferenced, the symvol for the inner pointer will have the nullability information. The lack of multi level annotation tracking only observable, when multiple levels of pointers are passed to a function which has a parameter with multiple levels of annotations. So for now the checker support the top level nullability qualifiers only.::
+.. code-block:: cpp
- int * __nonnull * __nullable p;
- int ** q = p;
- takesStarNullableStarNullable(q);
+ int * __nonnull * __nullable p;
+ int ** q = p;
+ takesStarNullableStarNullable(q);
Implementation notes
-============
+--------------------
What to track?
-- The checker would track memory regions, and to each relevant region a qualifier information would be attached which is either nullable, nonnull or null unspecified (or contradicted to suppress warnings for a specific region).
-- On a branch, where a nullable pointer is known to be non null, the checker treat it as a same way as a pointer annotated as nonnull.
-- When there is an explicit cast from a null unspecified to either nonnull or nullable I will trust the cast.
-- Unannotated pointers are treated the same way as pointers annotated with nullability unspecified qualifier, unless the region is wrapped in ASSUME_NONNULL macros.
-- We might want to implement a callback for entry points to top level functions, where the pointer nullability assumptions would be made.
+
+* The checker would track memory regions, and to each relevant region a qualifier information would be attached which is either nullable, nonnull or null unspecified (or contradicted to suppress warnings for a specific region).
+* On a branch, where a nullable pointer is known to be non null, the checker treat it as a same way as a pointer annotated as nonnull.
+* When there is an explicit cast from a null unspecified to either nonnull or nullable I will trust the cast.
+* Unannotated pointers are treated the same way as pointers annotated with nullability unspecified qualifier, unless the region is wrapped in ASSUME_NONNULL macros.
+* We might want to implement a callback for entry points to top level functions, where the pointer nullability assumptions would be made.
diff --git a/docs/analyzer/index.rst b/docs/analyzer/index.rst
deleted file mode 100644
index 767567f22f..0000000000
--- a/docs/analyzer/index.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-.. Clang Static Analyzer documentation master file, created by
- sphinx-quickstart on Wed Jan 2 15:54:28 2013.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-Welcome to Clang Static Analyzer's documentation!
-=================================================
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- DebugChecks
-
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
diff --git a/docs/conf.py b/docs/conf.py
index 19113d0d5a..dab70266d9 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -50,9 +50,9 @@ copyright = u'2007-%d, The Clang Team' % date.today().year
# built documents.
#
# The short version.
-version = '8'
+version = '9'
# The full version, including alpha/beta/rc tags.
-release = '8'
+release = '9'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -66,7 +66,7 @@ release = '8'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
-exclude_patterns = ['_build', 'analyzer']
+exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
diff --git a/docs/index.rst b/docs/index.rst
index 3eb1d160c7..73468705bc 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -23,6 +23,7 @@ Using Clang as a Compiler
AttributeReference
DiagnosticsReference
CrossCompilation
+ ClangStaticAnalyzer
ThreadSafetyAnalysis
AddressSanitizer
ThreadSanitizer