xref: /aosp_15_r20/external/clang/test/SemaCXX/warn-weak-vtables.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -fsyntax-only -verify -triple %itanium_abi_triple -Wweak-vtables -Wweak-template-vtables
2*67e74705SXin Li // RUN: %clang_cc1 %s -fsyntax-only -triple %ms_abi_triple -Werror -Wno-weak-vtables -Wno-weak-template-vtables
3*67e74705SXin Li 
4*67e74705SXin Li struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
fA5*67e74705SXin Li   virtual void f() { }
6*67e74705SXin Li };
7*67e74705SXin Li 
8*67e74705SXin Li template<typename T> struct B {
fB9*67e74705SXin Li   virtual void f() { }
10*67e74705SXin Li };
11*67e74705SXin Li 
12*67e74705SXin Li namespace {
13*67e74705SXin Li   struct C {
f__anon8a53444e0111::C14*67e74705SXin Li     virtual void f() { }
15*67e74705SXin Li   };
16*67e74705SXin Li }
17*67e74705SXin Li 
f()18*67e74705SXin Li void f() {
19*67e74705SXin Li   struct A {
20*67e74705SXin Li     virtual void f() { }
21*67e74705SXin Li   };
22*67e74705SXin Li 
23*67e74705SXin Li   A a;
24*67e74705SXin Li }
25*67e74705SXin Li 
26*67e74705SXin Li // Use the vtables
uses_abc()27*67e74705SXin Li void uses_abc() {
28*67e74705SXin Li   A a;
29*67e74705SXin Li   B<int> b;
30*67e74705SXin Li   C c;
31*67e74705SXin Li }
32*67e74705SXin Li 
33*67e74705SXin Li // <rdar://problem/9979458>
34*67e74705SXin Li class Parent {
35*67e74705SXin Li public:
Parent()36*67e74705SXin Li   Parent() {}
37*67e74705SXin Li   virtual ~Parent();
38*67e74705SXin Li   virtual void * getFoo() const = 0;
39*67e74705SXin Li };
40*67e74705SXin Li 
41*67e74705SXin Li class Derived : public Parent {
42*67e74705SXin Li public:
43*67e74705SXin Li   Derived();
44*67e74705SXin Li   void * getFoo() const;
45*67e74705SXin Li };
46*67e74705SXin Li 
47*67e74705SXin Li class VeryDerived : public Derived { // expected-warning{{'VeryDerived' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
48*67e74705SXin Li public:
getFoo() const49*67e74705SXin Li   void * getFoo() const { return 0; }
50*67e74705SXin Li };
51*67e74705SXin Li 
~Parent()52*67e74705SXin Li Parent::~Parent() {}
53*67e74705SXin Li 
uses_derived()54*67e74705SXin Li void uses_derived() {
55*67e74705SXin Li   Derived d;
56*67e74705SXin Li   VeryDerived vd;
57*67e74705SXin Li }
58*67e74705SXin Li 
59*67e74705SXin Li template<typename T> struct TemplVirt {
60*67e74705SXin Li   virtual void f();
61*67e74705SXin Li };
62*67e74705SXin Li 
63*67e74705SXin Li template class TemplVirt<float>; // expected-warning{{explicit template instantiation 'TemplVirt<float>' will emit a vtable in every translation unit}}
64*67e74705SXin Li 
65*67e74705SXin Li template<> struct TemplVirt<bool> {
66*67e74705SXin Li   virtual void f();
67*67e74705SXin Li };
68*67e74705SXin Li 
69*67e74705SXin Li template<> struct TemplVirt<long> { // expected-warning{{'TemplVirt<long>' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
fTemplVirt70*67e74705SXin Li   virtual void f() {}
71*67e74705SXin Li };
72*67e74705SXin Li 
uses_templ()73*67e74705SXin Li void uses_templ() {
74*67e74705SXin Li   TemplVirt<float> f;
75*67e74705SXin Li   TemplVirt<bool> b;
76*67e74705SXin Li   TemplVirt<long> l;
77*67e74705SXin Li }
78