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:


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to