// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.DeleteWithNonVirtualDtor -std=c++11 -verify -analyzer-output=text %s

struct Virtual {
  virtual ~Virtual() {}
};

struct VDerived : public Virtual {};

struct NonVirtual {
  ~NonVirtual() {}
};

struct NVDerived : public NonVirtual {};
struct NVDoubleDerived : public NVDerived {};

struct Base {
  virtual void destroy() = 0;
};

class PrivateDtor final : public Base {
public:
  void destroy() { delete this; }
private:
  ~PrivateDtor() {}
};

struct ImplicitNV {
  virtual void f();
};

struct ImplicitNVDerived : public ImplicitNV {};

NVDerived *get();

NonVirtual *create() {
  NonVirtual *x = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
  return x;
}

void sink(NonVirtual *x) {
  delete x; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void sinkCast(NonVirtual *y) {
  delete reinterpret_cast<NVDerived*>(y);
}

void sinkParamCast(NVDerived *z) {
  delete z;
}

void singleDerived() {
  NonVirtual *sd;
  sd = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
  delete sd; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void singleDerivedArr() {
  NonVirtual *sda = new NVDerived[5]; // expected-note{{Conversion from derived to base happened here}}
  delete[] sda; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void doubleDerived() {
  NonVirtual *dd = new NVDoubleDerived(); // expected-note{{Conversion from derived to base happened here}}
  delete (dd); // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void assignThroughFunction() {
  NonVirtual *atf = get(); // expected-note{{Conversion from derived to base happened here}}
  delete atf; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void assignThroughFunction2() {
  NonVirtual *atf2;
  atf2 = get(); // expected-note{{Conversion from derived to base happened here}}
  delete atf2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void createThroughFunction() {
  NonVirtual *ctf = create(); // expected-note{{Calling 'create'}}
  // expected-note@-1{{Returning from 'create'}}
  delete ctf; // expected-warning {{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void deleteThroughFunction() {
  NonVirtual *dtf = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
  sink(dtf); // expected-note{{Calling 'sink'}}
}

void singleCastCStyle() {
  NVDerived *sccs = new NVDerived();
  NonVirtual *sccs2 = (NonVirtual*)sccs; // expected-note{{Conversion from derived to base happened here}}
  delete sccs2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void doubleCastCStyle() {
  NonVirtual *dccs = new NVDerived();
  NVDerived *dccs2 = (NVDerived*)dccs;
  dccs = (NonVirtual*)dccs2; // expected-note{{Conversion from derived to base happened here}}
  delete dccs; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void singleCast() {
  NVDerived *sc = new NVDerived();
  NonVirtual *sc2 = reinterpret_cast<NonVirtual*>(sc); // expected-note{{Conversion from derived to base happened here}}
  delete sc2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void doubleCast() {
  NonVirtual *dd = new NVDerived();
  NVDerived *dd2 = reinterpret_cast<NVDerived*>(dd);
  dd = reinterpret_cast<NonVirtual*>(dd2); // expected-note {{Conversion from derived to base happened here}}
  delete dd; // expected-warning {{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void implicitNV() {
  ImplicitNV *invd = new ImplicitNVDerived(); // expected-note{{Conversion from derived to base happened here}}
  delete invd; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void doubleDecl() {
  ImplicitNV *dd1, *dd2;
  dd1 = new ImplicitNVDerived(); // expected-note{{Conversion from derived to base happened here}}
  delete dd1; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
}

void virtualBase() {
  Virtual *vb = new VDerived();
  delete vb; // no-warning
}

void notDerived() {
  NonVirtual *nd = new NonVirtual();
  delete nd; // no-warning
}

void notDerivedArr() {
  NonVirtual *nda = new NonVirtual[3];
  delete[] nda; // no-warning
}

void cast() {
  NonVirtual *c = new NVDerived();
  delete reinterpret_cast<NVDerived*>(c); // no-warning
}

void deleteThroughFunction2() {
  NonVirtual *dtf2 = new NVDerived();
  sinkCast(dtf2); // no-warning
}

void deleteThroughFunction3() {
  NVDerived *dtf3;
  dtf3 = new NVDerived();
  sinkParamCast(dtf3); // no-warning
}

void stackVar() {
  NonVirtual sv2;
  delete &sv2; // no-warning
}

// Deleting a polymorphic object with a non-virtual dtor
// is not a problem if it is referenced by its precise type.

void preciseType() {
  NVDerived *pt = new NVDerived();
  delete pt; // no-warning
}

void privateDtor() {
  Base *pd = new PrivateDtor();
  pd->destroy(); // no-warning
}
