blob: 1b32182c4f2ef6ce4188a2d7aa0cfc009009f58e [file] [log] [blame]
Stephen Hines176edba2014-12-01 14:53:08 -08001// RUN: %clang_cc1 -verify -std=c++11 %s
Stephen Hines0e2c34f2015-03-23 12:09:02 -07002// expected-no-diagnostics
Stephen Hines176edba2014-12-01 14:53:08 -08003template <typename T> struct OwnPtr {
4 T *p;
5 ~OwnPtr() {
Stephen Hines176edba2014-12-01 14:53:08 -08006 static_assert(sizeof(T) > 0, "incomplete T");
7 delete p;
8 }
9};
10
11namespace use_vtable_for_vcall {
Stephen Hines0e2c34f2015-03-23 12:09:02 -070012struct Incomplete;
Stephen Hines176edba2014-12-01 14:53:08 -080013struct A {
14 virtual ~A() {}
15 virtual void m() {}
16};
Stephen Hines0e2c34f2015-03-23 12:09:02 -070017struct B : A {
Stephen Hines176edba2014-12-01 14:53:08 -080018 B();
19 virtual void m() { }
20 virtual void m2() { static_cast<A *>(this)->m(); }
21 OwnPtr<Incomplete> m_sqlError;
22};
23
Stephen Hines0e2c34f2015-03-23 12:09:02 -070024void 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;
Stephen Hines176edba2014-12-01 14:53:08 -080030}
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}