xref: /llvm-project/clang/test/Analysis/ArrayDelete.cpp (revision 37785fedabd8fa752129ef5bac3462311af91c35)
1*37785fedSDiscookie // RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.ArrayDelete -std=c++11 -verify -analyzer-output=text %s
20e246bb6SViktor Cseh 
30e246bb6SViktor Cseh struct Base {
40e246bb6SViktor Cseh     virtual ~Base() = default;
50e246bb6SViktor Cseh };
60e246bb6SViktor Cseh 
70e246bb6SViktor Cseh struct Derived : public Base {};
80e246bb6SViktor Cseh 
90e246bb6SViktor Cseh struct DoubleDerived : public Derived {};
100e246bb6SViktor Cseh 
110e246bb6SViktor Cseh Derived *get();
120e246bb6SViktor Cseh 
create()130e246bb6SViktor Cseh Base *create() {
140e246bb6SViktor Cseh     Base *b = new Derived[3]; // expected-note{{Casting from 'Derived' to 'Base' here}}
150e246bb6SViktor Cseh     return b;
160e246bb6SViktor Cseh }
170e246bb6SViktor Cseh 
sink(Base * b)180e246bb6SViktor Cseh void sink(Base *b) {
190e246bb6SViktor Cseh     delete[] b; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
200e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
210e246bb6SViktor Cseh }
220e246bb6SViktor Cseh 
sink_cast(Base * b)230e246bb6SViktor Cseh void sink_cast(Base *b) {
240e246bb6SViktor Cseh     delete[] static_cast<Derived*>(b); // no-warning
250e246bb6SViktor Cseh }
260e246bb6SViktor Cseh 
sink_derived(Derived * d)270e246bb6SViktor Cseh void sink_derived(Derived *d) {
280e246bb6SViktor Cseh     delete[] d; // no-warning
290e246bb6SViktor Cseh }
300e246bb6SViktor Cseh 
same_function()310e246bb6SViktor Cseh void same_function() {
320e246bb6SViktor Cseh     Base *sd = new Derived[10]; // expected-note{{Casting from 'Derived' to 'Base' here}}
330e246bb6SViktor Cseh     delete[] sd; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
340e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
350e246bb6SViktor Cseh 
360e246bb6SViktor Cseh     Base *dd = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
370e246bb6SViktor Cseh     delete[] dd; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
380e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
390e246bb6SViktor Cseh }
400e246bb6SViktor Cseh 
different_function()410e246bb6SViktor Cseh void different_function() {
420e246bb6SViktor Cseh     Base *assigned = get(); // expected-note{{Casting from 'Derived' to 'Base' here}}
430e246bb6SViktor Cseh     delete[] assigned; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
440e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
450e246bb6SViktor Cseh 
460e246bb6SViktor Cseh     Base *indirect;
470e246bb6SViktor Cseh     indirect = get(); // expected-note{{Casting from 'Derived' to 'Base' here}}
480e246bb6SViktor Cseh     delete[] indirect; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
490e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
500e246bb6SViktor Cseh 
510e246bb6SViktor Cseh     Base *created = create(); // expected-note{{Calling 'create'}}
520e246bb6SViktor Cseh     // expected-note@-1{{Returning from 'create'}}
530e246bb6SViktor Cseh     delete[] created; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
540e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
550e246bb6SViktor Cseh 
560e246bb6SViktor Cseh     Base *sb = new Derived[10]; // expected-note{{Casting from 'Derived' to 'Base' here}}
570e246bb6SViktor Cseh     sink(sb); // expected-note{{Calling 'sink'}}
580e246bb6SViktor Cseh }
590e246bb6SViktor Cseh 
safe_function()600e246bb6SViktor Cseh void safe_function() {
610e246bb6SViktor Cseh     Derived *d = new Derived[10];
620e246bb6SViktor Cseh     delete[] d; // no-warning
630e246bb6SViktor Cseh 
640e246bb6SViktor Cseh     Base *b = new Derived[10];
650e246bb6SViktor Cseh     delete[] static_cast<Derived*>(b); // no-warning
660e246bb6SViktor Cseh 
670e246bb6SViktor Cseh     Base *sb = new Derived[10];
680e246bb6SViktor Cseh     sink_cast(sb); // no-warning
690e246bb6SViktor Cseh 
700e246bb6SViktor Cseh     Derived *sd = new Derived[10];
710e246bb6SViktor Cseh     sink_derived(sd); // no-warning
720e246bb6SViktor Cseh }
730e246bb6SViktor Cseh 
multiple_derived()740e246bb6SViktor Cseh void multiple_derived() {
750e246bb6SViktor Cseh     Base *b = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
760e246bb6SViktor Cseh     delete[] b; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
770e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
780e246bb6SViktor Cseh 
790e246bb6SViktor Cseh     Base *b2 = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
800e246bb6SViktor Cseh     Derived *d2 = static_cast<Derived*>(b2); // expected-note{{Casting from 'Base' to 'Derived' here}}
810e246bb6SViktor Cseh     delete[] d2; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
820e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
830e246bb6SViktor Cseh 
840e246bb6SViktor Cseh     Derived *d3 = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Derived' here}}
850e246bb6SViktor Cseh     Base *b3 = d3; // expected-note{{Casting from 'Derived' to 'Base' here}}
860e246bb6SViktor Cseh     delete[] b3; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
870e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
880e246bb6SViktor Cseh 
890e246bb6SViktor Cseh     Base *b4 = new DoubleDerived[10];
900e246bb6SViktor Cseh     Derived *d4 = static_cast<Derived*>(b4);
910e246bb6SViktor Cseh     DoubleDerived *dd4 = static_cast<DoubleDerived*>(d4);
920e246bb6SViktor Cseh     delete[] dd4; // no-warning
930e246bb6SViktor Cseh 
940e246bb6SViktor Cseh     Base *b5 = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
950e246bb6SViktor Cseh     DoubleDerived *dd5 = static_cast<DoubleDerived*>(b5); // expected-note{{Casting from 'Base' to 'DoubleDerived' here}}
960e246bb6SViktor Cseh     Derived *d5 = dd5; // expected-note{{Casting from 'DoubleDerived' to 'Derived' here}}
970e246bb6SViktor Cseh     delete[] d5; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
980e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
990e246bb6SViktor Cseh }
1000e246bb6SViktor Cseh 
unrelated_casts()1010e246bb6SViktor Cseh void unrelated_casts() {
1020e246bb6SViktor Cseh     Base *b = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
1030e246bb6SViktor Cseh     Base &b2 = *b; // no-note: See the FIXME.
1040e246bb6SViktor Cseh 
1050e246bb6SViktor Cseh     // FIXME: Displaying casts of reference types is not supported.
1060e246bb6SViktor Cseh     Derived &d2 = static_cast<Derived&>(b2); // no-note: See the FIXME.
1070e246bb6SViktor Cseh 
1080e246bb6SViktor Cseh     Derived *d = &d2; // no-note: See the FIXME.
1090e246bb6SViktor Cseh     delete[] d; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
1100e246bb6SViktor Cseh     // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
1110e246bb6SViktor Cseh }
112