1// RUN: %clang_cc1 -verify -std=c++11 %s
2// expected-no-diagnostics
3template <typename T> struct OwnPtr {
4  T *p;
5  ~OwnPtr() {
6    static_assert(sizeof(T) > 0, "incomplete T");
7    delete p;
8  }
9};
10
11namespace use_vtable_for_vcall {
12struct Incomplete;
13struct A {
14  virtual ~A() {}
15  virtual void m() {}
16};
17struct B : A {
18  B();
19  virtual void m() { }
20  virtual void m2() { static_cast<A *>(this)->m(); }
21  OwnPtr<Incomplete> m_sqlError;
22};
23
24void f() {
25  // Since B's constructor is declared out of line, nothing in this file
26  // references a vtable, so the destructor doesn't get built.
27  A *b = new B();
28  b->m();
29  delete b;
30}
31}
32
33namespace dont_mark_qualified_vcall {
34struct Incomplete;
35struct A {
36  virtual ~A() {}
37  virtual void m() {}
38};
39struct B : A {
40  B();
41  // Previously we would mark B's vtable referenced to devirtualize this call to
42  // A::m, even though it's not a virtual call.
43  virtual void m() { A::m(); }
44  OwnPtr<Incomplete> m_sqlError;
45};
46
47B *f() {
48  return new B();
49}
50}
51