@@ -543,6 +543,42 @@ Do not attempt to create a std::string from a null pointer
543
543
}
544
544
}
545
545
546
+ .. _cplusplus-PureVirtualCall :
547
+
548
+ cplusplus.PureVirtualCall (C++)
549
+ """""""""""""""""""""""""""""""
550
+
551
+ When `virtual methods are called during construction and destruction
552
+ <https://en.cppreference.com/w/cpp/language/virtual#During_construction_and_destruction> `__
553
+ the polymorphism is restricted to the class that's being constructed or
554
+ destructed because the more derived contexts are either not yet initialized or
555
+ already destructed.
556
+
557
+ This checker reports situations where this restricted polymorphism causes a
558
+ call to a pure virtual method, which is undefined behavior. (See also the
559
+ related checker :ref: `optin-cplusplus-VirtualCall ` which reports situations
560
+ where the restricted polymorphism affects a call and the called method is not
561
+ pure virtual – but may be still surprising for the programmer.)
562
+
563
+ .. code-block :: cpp
564
+
565
+ struct A {
566
+ virtual void getKind() = 0;
567
+
568
+ A() {
569
+ // warn: This calls the pure virtual method A::getKind().
570
+ log << "Constructing " << getKind();
571
+ }
572
+ virtual ~A() {
573
+ releaseResources();
574
+ }
575
+ void releaseResources() {
576
+ // warn: This can call the pure virtual method A::getKind() when this is
577
+ // called from the destructor.
578
+ callSomeFunction(getKind())
579
+ }
580
+ };
581
+
546
582
.. _deadcode-checkers :
547
583
548
584
deadcode
@@ -833,24 +869,40 @@ This checker has several options which can be set from command line (e.g.
833
869
834
870
optin.cplusplus .VirtualCall (C++)
835
871
"""""""""""""""""""""""""""""""""
836
- Check virtual function calls during construction or destruction.
872
+
873
+ When `virtual methods are called during construction and destruction
874
+ <https://en.cppreference.com/w/cpp/language/virtual#During_construction_and_destruction> `__
875
+ the polymorphism is restricted to the class that's being constructed or
876
+ destructed because the more derived contexts are either not yet initialized or
877
+ already destructed.
878
+
879
+ Although this behavior is well-defined, it can surprise the programmer and
880
+ cause unintended behavior, so this checker reports calls that appear to be
881
+ virtual calls but can be affected by this restricted polymorphism.
882
+
883
+ Note that situations where this restricted polymorphism causes a call to a pure
884
+ virtual method (which is definitely invalid, triggers undefined behavior) are
885
+ **reported by another checker: ** :ref: `cplusplus-PureVirtualCall ` and **this
886
+ checker does not report them **.
837
887
838
888
.. code-block :: cpp
839
889
840
- class A {
841
- public:
890
+ struct A {
891
+ virtual void getKind();
892
+
842
893
A() {
843
- f(); // warn
894
+ // warn: This calls A::getKind() even if we are constructing an instance
895
+ // of a different class that is derived from A.
896
+ log << "Constructing " << getKind();
844
897
}
845
- virtual void f();
846
- } ;
847
-
848
- class A {
849
- public:
850
- ~A() {
851
- this->f(); // warn
898
+ virtual ~A() {
899
+ releaseResources() ;
900
+ }
901
+ void releaseResources() {
902
+ // warn: This can be called within ~A() and calls A::getKind() even if
903
+ // we are destructing a class that is derived from A.
904
+ callSomeFunction(getKind())
852
905
}
853
- virtual void f();
854
906
};
855
907
856
908
.. _optin-mpi-MPI-Checker :
0 commit comments