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 CsehBase *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 Csehvoid 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 Csehvoid sink_cast(Base *b) { 240e246bb6SViktor Cseh delete[] static_cast<Derived*>(b); // no-warning 250e246bb6SViktor Cseh } 260e246bb6SViktor Cseh sink_derived(Derived * d)270e246bb6SViktor Csehvoid sink_derived(Derived *d) { 280e246bb6SViktor Cseh delete[] d; // no-warning 290e246bb6SViktor Cseh } 300e246bb6SViktor Cseh same_function()310e246bb6SViktor Csehvoid 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 Csehvoid 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 Csehvoid 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 Csehvoid 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 Csehvoid 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