Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
      2 namespace T1 {
      3 
      4 class A {
      5   virtual int f(); // expected-note{{overridden virtual function is here}}
      6 };
      7 
      8 class 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 
     14 namespace T2 {
     15 
     16 struct a { };
     17 struct b { };
     18 
     19 class A {
     20   virtual a* f(); // expected-note{{overridden virtual function is here}}
     21 };
     22 
     23 class 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 
     29 namespace T3 {
     30 
     31 struct a { };
     32 struct b : private a { }; // expected-note{{declared private here}}
     33 
     34 class A {
     35   virtual a* f(); // FIXME: desired-note{{overridden virtual function is here}}
     36 };
     37 
     38 class 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 
     44 namespace T4 {
     45 
     46 struct a { };
     47 struct a1 : a { };
     48 struct b : a, a1 { };
     49 
     50 class A {
     51   virtual a* f(); // expected-note{{overridden virtual function is here}}
     52 };
     53 
     54 class 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 
     62 namespace T5 {
     63 
     64 struct a { };
     65 
     66 class A {
     67   virtual a* const f();
     68   virtual a* const g(); // expected-note{{overridden virtual function is here}}
     69 };
     70 
     71 class 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 
     78 namespace T6 {
     79 
     80 struct a { };
     81 
     82 class A {
     83   virtual const a* f();
     84   virtual a* g(); // expected-note{{overridden virtual function is here}}
     85 };
     86 
     87 class 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 
     94 namespace 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 
    107 namespace 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 
    120 namespace 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
    137 class X0 {
    138   virtual void f0();
    139 };
    140 class X1 : public X0 {
    141   void f0() = 0;
    142 };
    143 
    144 template <typename Base>
    145 struct Foo : Base {
    146   void f(int) = 0; // expected-error{{not virtual and cannot be declared pure}}
    147 };
    148 
    149 struct Base1 { virtual void f(int); };
    150 struct Base2 { };
    151 
    152 void test() {
    153   (void)sizeof(Foo<Base1>);
    154   (void)sizeof(Foo<Base2>); // expected-note{{instantiation}}
    155 }
    156 
    157 template<typename Base>
    158 struct Foo2 : Base {
    159   template<typename T> int f(T);
    160 };
    161 
    162 void test2() {
    163   Foo2<Base1> f1;
    164   Foo2<Base2> f2;
    165   f1.f(17);
    166   f2.f(17);
    167 };
    168 
    169 struct Foo3 {
    170   virtual void f(int) = 0; // expected-note{{unimplemented pure virtual method}}
    171 };
    172 
    173 template<typename T>
    174 struct Bar3 : Foo3 {
    175   void f(T);
    176 };
    177 
    178 void test3() {
    179   Bar3<int> b3i; // okay
    180   Bar3<float> b3f; // expected-error{{is an abstract class}}
    181 }
    182 
    183 // 5920
    184 namespace 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.
    203 namespace 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.
    219 namespace 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 
    241 namespace 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 
    254 namespace 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 
    267 namespace 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 
    280 namespace 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