xref: /aosp_15_r20/external/clang/test/SemaCXX/devirtualize-vtable-marking.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -verify -std=c++11 %s
2*67e74705SXin Li // expected-no-diagnostics
3*67e74705SXin Li template <typename T> struct OwnPtr {
4*67e74705SXin Li   T *p;
~OwnPtrOwnPtr5*67e74705SXin Li   ~OwnPtr() {
6*67e74705SXin Li     static_assert(sizeof(T) > 0, "incomplete T");
7*67e74705SXin Li     delete p;
8*67e74705SXin Li   }
9*67e74705SXin Li };
10*67e74705SXin Li 
11*67e74705SXin Li namespace use_vtable_for_vcall {
12*67e74705SXin Li struct Incomplete;
13*67e74705SXin Li struct A {
~Ause_vtable_for_vcall::A14*67e74705SXin Li   virtual ~A() {}
muse_vtable_for_vcall::A15*67e74705SXin Li   virtual void m() {}
16*67e74705SXin Li };
17*67e74705SXin Li struct B : A {
18*67e74705SXin Li   B();
muse_vtable_for_vcall::B19*67e74705SXin Li   virtual void m() { }
m2use_vtable_for_vcall::B20*67e74705SXin Li   virtual void m2() { static_cast<A *>(this)->m(); }
21*67e74705SXin Li   OwnPtr<Incomplete> m_sqlError;
22*67e74705SXin Li };
23*67e74705SXin Li 
f()24*67e74705SXin Li void f() {
25*67e74705SXin Li   // Since B's constructor is declared out of line, nothing in this file
26*67e74705SXin Li   // references a vtable, so the destructor doesn't get built.
27*67e74705SXin Li   A *b = new B();
28*67e74705SXin Li   b->m();
29*67e74705SXin Li   delete b;
30*67e74705SXin Li }
31*67e74705SXin Li }
32*67e74705SXin Li 
33*67e74705SXin Li namespace dont_mark_qualified_vcall {
34*67e74705SXin Li struct Incomplete;
35*67e74705SXin Li struct A {
~Adont_mark_qualified_vcall::A36*67e74705SXin Li   virtual ~A() {}
mdont_mark_qualified_vcall::A37*67e74705SXin Li   virtual void m() {}
38*67e74705SXin Li };
39*67e74705SXin Li struct B : A {
40*67e74705SXin Li   B();
41*67e74705SXin Li   // Previously we would mark B's vtable referenced to devirtualize this call to
42*67e74705SXin Li   // A::m, even though it's not a virtual call.
mdont_mark_qualified_vcall::B43*67e74705SXin Li   virtual void m() { A::m(); }
44*67e74705SXin Li   OwnPtr<Incomplete> m_sqlError;
45*67e74705SXin Li };
46*67e74705SXin Li 
f()47*67e74705SXin Li B *f() {
48*67e74705SXin Li   return new B();
49*67e74705SXin Li }
50*67e74705SXin Li }
51