virtual-override.cpp revision 762bb9d0ad20320b9f97a841dce57ba5e8e48b07
1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2namespace T1 {
3
4class A {
5  virtual int f(); // expected-note{{overridden virtual function is here}}
6};
7
8class B : A {
9  virtual void f(); // expected-error{{virtual function 'f' has a different return type ('void') than the function it overrides (which has return type 'int')}}
10};
11
12}
13
14namespace T2 {
15
16struct a { };
17struct b { };
18
19class A {
20  virtual a* f(); // expected-note{{overridden virtual function is here}}
21};
22
23class B : A {
24  virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('T2::b *' is not derived from 'T2::a *')}}
25};
26
27}
28
29namespace T3 {
30
31struct a { };
32struct b : private a { }; // expected-note{{declared private here}}
33
34class A {
35  virtual a* f(); // FIXME: desired-note{{overridden virtual function is here}}
36};
37
38class B : A {
39  virtual b* f(); // expected-error{{invalid covariant return for virtual function: 'T3::a' is a private base class of 'T3::b'}}
40};
41
42}
43
44namespace T4 {
45
46struct a { };
47struct a1 : a { };
48struct b : a, a1 { };
49
50class A {
51  virtual a* f(); // expected-note{{overridden virtual function is here}}
52};
53
54class B : A {
55  virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides (ambiguous conversion from derived class 'T4::b' to base class 'T4::a':\n\
56    struct T4::b -> struct T4::a\n\
57    struct T4::b -> struct T4::a1 -> struct T4::a)}}
58};
59
60}
61
62namespace T5 {
63
64struct a { };
65
66class A {
67  virtual a* const f();
68  virtual a* const g(); // expected-note{{overridden virtual function is here}}
69};
70
71class B : A {
72  virtual a* const f();
73  virtual a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides ('T5::a *' has different qualifiers than 'T5::a *const')}}
74};
75
76}
77
78namespace T6 {
79
80struct a { };
81
82class A {
83  virtual const a* f();
84  virtual a* g(); // expected-note{{overridden virtual function is here}}
85};
86
87class B : A {
88  virtual a* f();
89  virtual const a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides (class type 'const T6::a *' is more qualified than class type 'T6::a *'}}
90};
91
92}
93
94namespace T7 {
95  struct a { };
96  struct b { };
97
98  class A {
99    a* f();
100  };
101
102  class B : A {
103    virtual b* f();
104  };
105}
106
107namespace T8 {
108  struct a { };
109  struct b; // expected-note {{forward declaration of 'T8::b'}}
110
111  class A {
112    virtual a *f();
113  };
114
115  class B : A {
116    b* f(); // expected-error {{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('T8::b' is incomplete)}}
117  };
118}
119
120namespace T9 {
121  struct a { };
122
123  template<typename T> struct b : a {
124    int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}}
125  };
126
127  class A {
128    virtual a *f();
129  };
130
131  class B : A {
132    virtual b<int> *f(); // expected-note {{in instantiation of template class 'T9::b<int>' requested here}}
133  };
134}
135
136// PR5656
137class X0 {
138  virtual void f0();
139};
140class X1 : public X0 {
141  void f0() = 0;
142};
143
144template <typename Base>
145struct Foo : Base {
146  void f(int) = 0; // expected-error{{not virtual and cannot be declared pure}}
147};
148
149struct Base1 { virtual void f(int); };
150struct Base2 { };
151
152void test() {
153  (void)sizeof(Foo<Base1>);
154  (void)sizeof(Foo<Base2>); // expected-note{{instantiation}}
155}
156
157template<typename Base>
158struct Foo2 : Base {
159  template<typename T> int f(T);
160};
161
162void test2() {
163  Foo2<Base1> f1;
164  Foo2<Base2> f2;
165  f1.f(17);
166  f2.f(17);
167};
168
169struct Foo3 {
170  virtual void f(int) = 0; // expected-note{{unimplemented pure virtual method}}
171};
172
173template<typename T>
174struct Bar3 : Foo3 {
175  void f(T);
176};
177
178void test3() {
179  Bar3<int> b3i; // okay
180  Bar3<float> b3f; // expected-error{{is an abstract class}}
181}
182
183// 5920
184namespace PR5920 {
185  class Base {};
186
187  template <typename T>
188  class Derived : public Base {};
189
190  class Foo {
191   public:
192    virtual Base* Method();
193  };
194
195  class Bar : public Foo {
196   public:
197    virtual Derived<int>* Method();
198  };
199}
200
201// Look through template types and typedefs to see whether return types are
202// pointers or references.
203namespace PR6110 {
204  class Base {};
205  class Derived : public Base {};
206
207  typedef Base* BaseP;
208  typedef Derived* DerivedP;
209
210  class X { virtual BaseP f(); };
211  class X1 : public X { virtual DerivedP f(); };
212
213  template <typename T> class Y { virtual T f(); };
214  template <typename T1, typename T> class Y1 : public Y<T> { virtual T1 f(); };
215  Y1<Derived*, Base*> y;
216}
217
218// Defer checking for covariance if either return type is dependent.
219namespace type_dependent_covariance {
220  struct B {};
221  template <int N> struct TD : public B {};
222  template <> struct TD<1> {};
223
224  template <int N> struct TB {};
225  struct D : public TB<0> {};
226
227  template <int N> struct X {
228    virtual B* f1(); // expected-note{{overridden virtual function is here}}
229    virtual TB<N>* f2(); // expected-note{{overridden virtual function is here}}
230  };
231  template <int N, int M> struct X1 : X<N> {
232    virtual TD<M>* f1(); // expected-error{{return type of virtual function 'f1' is not covariant with the return type of the function it overrides ('TD<1> *'}}
233    virtual D* f2(); // expected-error{{return type of virtual function 'f2' is not covariant with the return type of the function it overrides ('type_dependent_covariance::D *' is not derived from 'TB<1> *')}}
234  };
235
236  X1<0, 0> good;
237  X1<0, 1> bad_derived; // expected-note{{instantiation}}
238  X1<1, 0> bad_base; // expected-note{{instantiation}}
239}
240
241namespace T10 {
242  struct A { };
243  struct B : A { };
244
245  struct C {
246    virtual A&& f();
247  };
248
249  struct D : C {
250    virtual B&& f();
251  };
252};
253
254namespace T11 {
255  struct A { };
256  struct B : A { };
257
258  struct C {
259    virtual A& f(); // expected-note {{overridden virtual function is here}}
260  };
261
262  struct D : C {
263    virtual B&& f(); // expected-error {{virtual function 'f' has a different return type ('T11::B &&') than the function it overrides (which has return type 'T11::A &')}}
264  };
265};
266
267namespace T12 {
268  struct A { };
269  struct B : A { };
270
271  struct C {
272    virtual A&& f(); // expected-note {{overridden virtual function is here}}
273  };
274
275  struct D : C {
276    virtual B& f(); // expected-error {{virtual function 'f' has a different return type ('T12::B &') than the function it overrides (which has return type 'T12::A &&')}}
277  };
278};
279
280namespace PR8168 {
281  class A {
282  public:
283    virtual void foo() {} // expected-note{{overridden virtual function is here}}
284  };
285
286  class B : public A {
287  public:
288    static void foo() {} // expected-error{{'static' member function 'foo' overrides a virtual function}}
289  };
290}
291