blob: 1b32182c4f2ef6ce4188a2d7aa0cfc009009f58e [file] [log] [blame]
Reid Kleckner5c553e32014-09-16 22:23:33 +00001// RUN: %clang_cc1 -verify -std=c++11 %s
Nico Weberb3a99782015-01-26 06:23:36 +00002// expected-no-diagnostics
Reid Kleckner5c553e32014-09-16 22:23:33 +00003template <typename T> struct OwnPtr {
4 T *p;
5 ~OwnPtr() {
Reid Kleckner5c553e32014-09-16 22:23:33 +00006 static_assert(sizeof(T) > 0, "incomplete T");
7 delete p;
8 }
9};
10
11namespace use_vtable_for_vcall {
Nico Weberb3a99782015-01-26 06:23:36 +000012struct Incomplete;
Reid Kleckner5c553e32014-09-16 22:23:33 +000013struct A {
14 virtual ~A() {}
15 virtual void m() {}
16};
Nico Weberb3a99782015-01-26 06:23:36 +000017struct B : A {
Reid Kleckner5c553e32014-09-16 22:23:33 +000018 B();
19 virtual void m() { }
20 virtual void m2() { static_cast<A *>(this)->m(); }
21 OwnPtr<Incomplete> m_sqlError;
22};
23
Nico Weberb3a99782015-01-26 06:23:36 +000024void 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;
Reid Kleckner5c553e32014-09-16 22:23:33 +000030}
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}