llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Donát Nagy (NagyDonat) <details> <summary>Changes</summary> 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. ----------- Screenshots of the HTML output:   In the introductory paragraphs I'm linking to [the relevant section of cppreference](https://en.cppreference.com/w/cpp/language/virtual#During_construction_and_destruction) because that seems to be an useful description of the issue that's being reported by this checker. (In general, I feel that it would be nice to add similar cppreference links in our docs when they're warranted.) --- Full diff: https://github.com/llvm/llvm-project/pull/131861.diff 1 Files Affected: - (modified) clang/docs/analyzer/checkers.rst (+64-12) ``````````diff 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 different 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: `````````` </details> https://github.com/llvm/llvm-project/pull/131861 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits