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