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