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