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