15c553e37SReid Kleckner // RUN: %clang_cc1 -verify -std=c++11 %s 2*b3a9978dSNico Weber // expected-no-diagnostics 35c553e37SReid Kleckner template <typename T> struct OwnPtr { 45c553e37SReid Kleckner T *p; ~OwnPtrOwnPtr55c553e37SReid Kleckner ~OwnPtr() { 65c553e37SReid Kleckner static_assert(sizeof(T) > 0, "incomplete T"); 75c553e37SReid Kleckner delete p; 85c553e37SReid Kleckner } 95c553e37SReid Kleckner }; 105c553e37SReid Kleckner 115c553e37SReid Kleckner namespace use_vtable_for_vcall { 12*b3a9978dSNico Weber struct Incomplete; 135c553e37SReid Kleckner struct A { ~Ause_vtable_for_vcall::A145c553e37SReid Kleckner virtual ~A() {} muse_vtable_for_vcall::A155c553e37SReid Kleckner virtual void m() {} 165c553e37SReid Kleckner }; 17*b3a9978dSNico Weber struct B : A { 185c553e37SReid Kleckner B(); muse_vtable_for_vcall::B195c553e37SReid Kleckner virtual void m() { } m2use_vtable_for_vcall::B205c553e37SReid Kleckner virtual void m2() { static_cast<A *>(this)->m(); } 215c553e37SReid Kleckner OwnPtr<Incomplete> m_sqlError; 225c553e37SReid Kleckner }; 235c553e37SReid Kleckner f()24*b3a9978dSNico Webervoid f() { 25*b3a9978dSNico Weber // Since B's constructor is declared out of line, nothing in this file 26*b3a9978dSNico Weber // references a vtable, so the destructor doesn't get built. 27*b3a9978dSNico Weber A *b = new B(); 28*b3a9978dSNico Weber b->m(); 29*b3a9978dSNico Weber delete b; 305c553e37SReid Kleckner } 315c553e37SReid Kleckner } 325c553e37SReid Kleckner 335c553e37SReid Kleckner namespace dont_mark_qualified_vcall { 345c553e37SReid Kleckner struct Incomplete; 355c553e37SReid Kleckner struct A { ~Adont_mark_qualified_vcall::A365c553e37SReid Kleckner virtual ~A() {} mdont_mark_qualified_vcall::A375c553e37SReid Kleckner virtual void m() {} 385c553e37SReid Kleckner }; 395c553e37SReid Kleckner struct B : A { 405c553e37SReid Kleckner B(); 415c553e37SReid Kleckner // Previously we would mark B's vtable referenced to devirtualize this call to 425c553e37SReid Kleckner // A::m, even though it's not a virtual call. mdont_mark_qualified_vcall::B435c553e37SReid Kleckner virtual void m() { A::m(); } 445c553e37SReid Kleckner OwnPtr<Incomplete> m_sqlError; 455c553e37SReid Kleckner }; 465c553e37SReid Kleckner f()475c553e37SReid KlecknerB *f() { 485c553e37SReid Kleckner return new B(); 495c553e37SReid Kleckner } 505c553e37SReid Kleckner } 51