1 // RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.DeleteWithNonVirtualDtor -std=c++11 -verify -analyzer-output=text %s
7 struct VDerived
: public Virtual
{};
13 struct NVDerived
: public NonVirtual
{};
14 struct NVDoubleDerived
: public NVDerived
{};
17 virtual void destroy() = 0;
20 class PrivateDtor final
: public Base
{
22 void destroy() { delete this; }
31 struct ImplicitNVDerived
: public ImplicitNV
{};
35 NonVirtual
*create() {
36 NonVirtual
*x
= new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
40 void sink(NonVirtual
*x
) {
41 delete x
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
42 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
45 void sinkCast(NonVirtual
*y
) {
46 delete reinterpret_cast<NVDerived
*>(y
);
49 void sinkParamCast(NVDerived
*z
) {
53 void singleDerived() {
55 sd
= new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
56 delete sd
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
57 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
60 void singleDerivedArr() {
61 NonVirtual
*sda
= new NVDerived
[5]; // expected-note{{Conversion from derived to base happened here}}
62 delete[] sda
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
63 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
66 void doubleDerived() {
67 NonVirtual
*dd
= new NVDoubleDerived(); // expected-note{{Conversion from derived to base happened here}}
68 delete (dd
); // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
69 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
72 void assignThroughFunction() {
73 NonVirtual
*atf
= get(); // expected-note{{Conversion from derived to base happened here}}
74 delete atf
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
75 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
78 void assignThroughFunction2() {
80 atf2
= get(); // expected-note{{Conversion from derived to base happened here}}
81 delete atf2
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
82 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
85 void createThroughFunction() {
86 NonVirtual
*ctf
= create(); // expected-note{{Calling 'create'}}
87 // expected-note@-1{{Returning from 'create'}}
88 delete ctf
; // expected-warning {{Destruction of a polymorphic object with no virtual destructor}}
89 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
92 void deleteThroughFunction() {
93 NonVirtual
*dtf
= new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
94 sink(dtf
); // expected-note{{Calling 'sink'}}
97 void singleCastCStyle() {
98 NVDerived
*sccs
= new NVDerived();
99 NonVirtual
*sccs2
= (NonVirtual
*)sccs
; // expected-note{{Conversion from derived to base happened here}}
100 delete sccs2
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
101 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
104 void doubleCastCStyle() {
105 NonVirtual
*dccs
= new NVDerived();
106 NVDerived
*dccs2
= (NVDerived
*)dccs
;
107 dccs
= (NonVirtual
*)dccs2
; // expected-note{{Conversion from derived to base happened here}}
108 delete dccs
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
109 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
113 NVDerived
*sc
= new NVDerived();
114 NonVirtual
*sc2
= reinterpret_cast<NonVirtual
*>(sc
); // expected-note{{Conversion from derived to base happened here}}
115 delete sc2
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
116 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
120 NonVirtual
*dd
= new NVDerived();
121 NVDerived
*dd2
= reinterpret_cast<NVDerived
*>(dd
);
122 dd
= reinterpret_cast<NonVirtual
*>(dd2
); // expected-note {{Conversion from derived to base happened here}}
123 delete dd
; // expected-warning {{Destruction of a polymorphic object with no virtual destructor}}
124 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
128 ImplicitNV
*invd
= new ImplicitNVDerived(); // expected-note{{Conversion from derived to base happened here}}
129 delete invd
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
130 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
134 ImplicitNV
*dd1
, *dd2
;
135 dd1
= new ImplicitNVDerived(); // expected-note{{Conversion from derived to base happened here}}
136 delete dd1
; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
137 // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
141 Virtual
*vb
= new VDerived();
142 delete vb
; // no-warning
146 NonVirtual
*nd
= new NonVirtual();
147 delete nd
; // no-warning
150 void notDerivedArr() {
151 NonVirtual
*nda
= new NonVirtual
[3];
152 delete[] nda
; // no-warning
156 NonVirtual
*c
= new NVDerived();
157 delete reinterpret_cast<NVDerived
*>(c
); // no-warning
160 void deleteThroughFunction2() {
161 NonVirtual
*dtf2
= new NVDerived();
162 sinkCast(dtf2
); // no-warning
165 void deleteThroughFunction3() {
167 dtf3
= new NVDerived();
168 sinkParamCast(dtf3
); // no-warning
173 delete &sv2
; // no-warning
176 // Deleting a polymorphic object with a non-virtual dtor
177 // is not a problem if it is referenced by its precise type.
180 NVDerived
*pt
= new NVDerived();
181 delete pt
; // no-warning
185 Base
*pd
= new PrivateDtor();
186 pd
->destroy(); // no-warning