1 // RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.ArrayDelete -std=c++11 -verify -analyzer-output=text %s
4 virtual ~Base() = default;
7 struct Derived
: public Base
{};
9 struct DoubleDerived
: public Derived
{};
14 Base
*b
= new Derived
[3]; // expected-note{{Casting from 'Derived' to 'Base' here}}
19 delete[] b
; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
20 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
23 void sink_cast(Base
*b
) {
24 delete[] static_cast<Derived
*>(b
); // no-warning
27 void sink_derived(Derived
*d
) {
28 delete[] d
; // no-warning
31 void same_function() {
32 Base
*sd
= new Derived
[10]; // expected-note{{Casting from 'Derived' to 'Base' here}}
33 delete[] sd
; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
34 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
36 Base
*dd
= new DoubleDerived
[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
37 delete[] dd
; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
38 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
41 void different_function() {
42 Base
*assigned
= get(); // expected-note{{Casting from 'Derived' to 'Base' here}}
43 delete[] assigned
; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
44 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
47 indirect
= get(); // expected-note{{Casting from 'Derived' to 'Base' here}}
48 delete[] indirect
; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
49 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
51 Base
*created
= create(); // expected-note{{Calling 'create'}}
52 // expected-note@-1{{Returning from 'create'}}
53 delete[] created
; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
54 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
56 Base
*sb
= new Derived
[10]; // expected-note{{Casting from 'Derived' to 'Base' here}}
57 sink(sb
); // expected-note{{Calling 'sink'}}
60 void safe_function() {
61 Derived
*d
= new Derived
[10];
62 delete[] d
; // no-warning
64 Base
*b
= new Derived
[10];
65 delete[] static_cast<Derived
*>(b
); // no-warning
67 Base
*sb
= new Derived
[10];
68 sink_cast(sb
); // no-warning
70 Derived
*sd
= new Derived
[10];
71 sink_derived(sd
); // no-warning
74 void multiple_derived() {
75 Base
*b
= new DoubleDerived
[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
76 delete[] b
; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
77 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
79 Base
*b2
= new DoubleDerived
[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
80 Derived
*d2
= static_cast<Derived
*>(b2
); // expected-note{{Casting from 'Base' to 'Derived' here}}
81 delete[] d2
; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
82 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
84 Derived
*d3
= new DoubleDerived
[10]; // expected-note{{Casting from 'DoubleDerived' to 'Derived' here}}
85 Base
*b3
= d3
; // expected-note{{Casting from 'Derived' to 'Base' here}}
86 delete[] b3
; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
87 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
89 Base
*b4
= new DoubleDerived
[10];
90 Derived
*d4
= static_cast<Derived
*>(b4
);
91 DoubleDerived
*dd4
= static_cast<DoubleDerived
*>(d4
);
92 delete[] dd4
; // no-warning
94 Base
*b5
= new DoubleDerived
[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
95 DoubleDerived
*dd5
= static_cast<DoubleDerived
*>(b5
); // expected-note{{Casting from 'Base' to 'DoubleDerived' here}}
96 Derived
*d5
= dd5
; // expected-note{{Casting from 'DoubleDerived' to 'Derived' here}}
97 delete[] d5
; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
98 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
101 void unrelated_casts() {
102 Base
*b
= new DoubleDerived
[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
103 Base
&b2
= *b
; // no-note: See the FIXME.
105 // FIXME: Displaying casts of reference types is not supported.
106 Derived
&d2
= static_cast<Derived
&>(b2
); // no-note: See the FIXME.
108 Derived
*d
= &d2
; // no-note: See the FIXME.
109 delete[] d
; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
110 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}