brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · 68ae1ae Raw
188 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.DeleteWithNonVirtualDtor -std=c++11 -verify -analyzer-output=text %s2 3struct Virtual {4  virtual ~Virtual() {}5};6 7struct VDerived : public Virtual {};8 9struct NonVirtual {10  ~NonVirtual() {}11};12 13struct NVDerived : public NonVirtual {};14struct NVDoubleDerived : public NVDerived {};15 16struct Base {17  virtual void destroy() = 0;18};19 20class PrivateDtor final : public Base {21public:22  void destroy() { delete this; }23private:24  ~PrivateDtor() {}25};26 27struct ImplicitNV {28  virtual void f();29};30 31struct ImplicitNVDerived : public ImplicitNV {};32 33NVDerived *get();34 35NonVirtual *create() {36  NonVirtual *x = new NVDerived(); // expected-note{{Casting from 'NVDerived' to 'NonVirtual' here}}37  return x;38}39 40void 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}}43}44 45void sinkCast(NonVirtual *y) {46  delete reinterpret_cast<NVDerived*>(y);47}48 49void sinkParamCast(NVDerived *z) {50  delete z;51}52 53void singleDerived() {54  NonVirtual *sd;55  sd = new NVDerived(); // expected-note{{Casting from 'NVDerived' to 'NonVirtual' 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}}58}59 60void singleDerivedArr() {61  NonVirtual *sda = new NVDerived[5]; // expected-note{{Casting from 'NVDerived' to 'NonVirtual' 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}}64}65 66void doubleDerived() {67  NonVirtual *dd = new NVDoubleDerived(); // expected-note{{Casting from 'NVDoubleDerived' to 'NonVirtual' 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}}70}71 72void assignThroughFunction() {73  NonVirtual *atf = get(); // expected-note{{Casting from 'NVDerived' to 'NonVirtual' 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}}76}77 78void assignThroughFunction2() {79  NonVirtual *atf2;80  atf2 = get(); // expected-note{{Casting from 'NVDerived' to 'NonVirtual' 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}}83}84 85void 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}}90}91 92void deleteThroughFunction() {93  NonVirtual *dtf = new NVDerived(); // expected-note{{Casting from 'NVDerived' to 'NonVirtual' here}}94  sink(dtf); // expected-note{{Calling 'sink'}}95}96 97void singleCastCStyle() {98  NVDerived *sccs = new NVDerived();99  NonVirtual *sccs2 = (NonVirtual*)sccs; // expected-note{{Casting from 'NVDerived' to 'NonVirtual' 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}}102}103 104void doubleCastCStyle() {105  NonVirtual *dccs = new NVDerived(); // expected-note{{Casting from 'NVDerived' to 'NonVirtual' here}}106  NVDerived *dccs2 = (NVDerived*)dccs; // expected-note{{Casting from 'NonVirtual' to 'NVDerived' here}}107  dccs = (NonVirtual*)dccs2; // expected-note{{Casting from 'NVDerived' to 'NonVirtual' 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}}110}111 112void singleCast() {113  NVDerived *sc = new NVDerived();114  NonVirtual *sc2 = reinterpret_cast<NonVirtual*>(sc); // expected-note{{Casting from 'NVDerived' to 'NonVirtual' 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}}117}118 119void doubleCast() {120  NonVirtual *dd = new NVDerived(); // expected-note {{Casting from 'NVDerived' to 'NonVirtual' here}}121  NVDerived *dd2 = reinterpret_cast<NVDerived*>(dd); // expected-note {{Casting from 'NonVirtual' to 'NVDerived' here}}122  dd = reinterpret_cast<NonVirtual*>(dd2); // expected-note {{Casting from 'NVDerived' to 'NonVirtual' 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}}125}126 127void implicitNV() {128  ImplicitNV *invd = new ImplicitNVDerived(); // expected-note{{Casting from 'ImplicitNVDerived' to 'ImplicitNV' 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}}131}132 133void doubleDecl() {134  ImplicitNV *dd1, *dd2;135  dd1 = new ImplicitNVDerived(); // expected-note{{Casting from 'ImplicitNVDerived' to 'ImplicitNV' 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}}138}139 140void virtualBase() {141  Virtual *vb = new VDerived();142  delete vb; // no-warning143}144 145void notDerived() {146  NonVirtual *nd = new NonVirtual();147  delete nd; // no-warning148}149 150void notDerivedArr() {151  NonVirtual *nda = new NonVirtual[3];152  delete[] nda; // no-warning153}154 155void cast() {156  NonVirtual *c = new NVDerived();157  delete reinterpret_cast<NVDerived*>(c); // no-warning158}159 160void deleteThroughFunction2() {161  NonVirtual *dtf2 = new NVDerived();162  sinkCast(dtf2); // no-warning163}164 165void deleteThroughFunction3() {166  NVDerived *dtf3;167  dtf3 = new NVDerived();168  sinkParamCast(dtf3); // no-warning169}170 171void stackVar() {172  NonVirtual sv2;173  delete &sv2; // no-warning174}175 176// Deleting a polymorphic object with a non-virtual dtor177// is not a problem if it is referenced by its precise type.178 179void preciseType() {180  NVDerived *pt = new NVDerived();181  delete pt; // no-warning182}183 184void privateDtor() {185  Base *pd = new PrivateDtor();186  pd->destroy(); // no-warning187}188