[clang] 9762b8e - [NFC][analyzer] Document the VirtualCall checkers (#131861)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 19 02:54:10 PDT 2025
Author: Donát Nagy
Date: 2025-03-19T10:54:06+01:00
New Revision: 9762b8e1757601a719d926f7df77c207617adfdd
URL: https://github.com/llvm/llvm-project/commit/9762b8e1757601a719d926f7df77c207617adfdd
DIFF: https://github.com/llvm/llvm-project/commit/9762b8e1757601a719d926f7df77c207617adfdd.diff
LOG: [NFC][analyzer] Document the VirtualCall checkers (#131861)
This commit documents `cplusplus.PureVirtualCall` (which was previously
completely undocumented) and improves the documentation of
`optin.cplusplus.VirtualCall` (which was very barebones).
Note that in this documentation I do not mention the checker options of
`optin.cplusplus.VirtualCall`, because `ShowFixIts` is apparently in an
unfinished alpha state (since 2019 when it was added by commit
6cee434ed10ead6b7416ca5ee9592b2b207eeb0f) and `PureOnly` is a deprecated
option that I'm going to remove very soon.
Added:
Modified:
clang/docs/analyzer/checkers.rst
Removed:
################################################################################
diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index 28286a8a5dba6..f3243d002bd35 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -543,6 +543,42 @@ Do not attempt to create a std::string from a null pointer
}
}
+.. _cplusplus-PureVirtualCall:
+
+cplusplus.PureVirtualCall (C++)
+"""""""""""""""""""""""""""""""
+
+When `virtual methods are called during construction and destruction
+<https://en.cppreference.com/w/cpp/language/virtual#During_construction_and_destruction>`__
+the polymorphism is restricted to the class that's being constructed or
+destructed because the more derived contexts are either not yet initialized or
+already destructed.
+
+This checker reports situations where this restricted polymorphism causes a
+call to a pure virtual method, which is undefined behavior. (See also the
+related checker :ref:`optin-cplusplus-VirtualCall` which reports situations
+where the restricted polymorphism affects a call and the called method is not
+pure virtual – but may be still surprising for the programmer.)
+
+.. code-block:: cpp
+
+ struct A {
+ virtual void getKind() = 0;
+
+ A() {
+ // warn: This calls the pure virtual method A::getKind().
+ log << "Constructing " << getKind();
+ }
+ virtual ~A() {
+ releaseResources();
+ }
+ void releaseResources() {
+ // warn: This can call the pure virtual method A::getKind() when this is
+ // called from the destructor.
+ callSomeFunction(getKind())
+ }
+ };
+
.. _deadcode-checkers:
deadcode
@@ -833,24 +869,40 @@ This checker has several options which can be set from command line (e.g.
optin.cplusplus.VirtualCall (C++)
"""""""""""""""""""""""""""""""""
-Check virtual function calls during construction or destruction.
+
+When `virtual methods are called during construction and destruction
+<https://en.cppreference.com/w/cpp/language/virtual#During_construction_and_destruction>`__
+the polymorphism is restricted to the class that's being constructed or
+destructed because the more derived contexts are either not yet initialized or
+already destructed.
+
+Although this behavior is well-defined, it can surprise the programmer and
+cause unintended behavior, so this checker reports calls that appear to be
+virtual calls but can be affected by this restricted polymorphism.
+
+Note that situations where this restricted polymorphism causes a call to a pure
+virtual method (which is definitely invalid, triggers undefined behavior) are
+**reported by another checker:** :ref:`cplusplus-PureVirtualCall` and **this
+checker does not report them**.
.. code-block:: cpp
- class A {
- public:
+ struct A {
+ virtual void getKind();
+
A() {
- f(); // warn
+ // warn: This calls A::getKind() even if we are constructing an instance
+ // of a
diff erent class that is derived from A.
+ log << "Constructing " << getKind();
}
- virtual void f();
- };
-
- class A {
- public:
- ~A() {
- this->f(); // warn
+ virtual ~A() {
+ releaseResources();
+ }
+ void releaseResources() {
+ // warn: This can be called within ~A() and calls A::getKind() even if
+ // we are destructing a class that is derived from A.
+ callSomeFunction(getKind())
}
- virtual void f();
};
.. _optin-mpi-MPI-Checker:
More information about the cfe-commits
mailing list