forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			292 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			292 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s -std=c++11
 | |
| // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -verify %s -std=c++11
 | |
| namespace T1 {
 | |
| 
 | |
| class A {
 | |
|   virtual int f(); // expected-note{{overridden virtual function is here}}
 | |
| };
 | |
| 
 | |
| class B : A {
 | |
|   virtual void f(); // expected-error{{virtual function 'f' has a different return type ('void') than the function it overrides (which has return type 'int')}}
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace T2 {
 | |
| 
 | |
| struct a { };
 | |
| struct b { };
 | |
|   
 | |
| class A {
 | |
|   virtual a* f(); // expected-note{{overridden virtual function is here}}
 | |
| };
 | |
| 
 | |
| class B : A {
 | |
|   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 *')}}
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace T3 {
 | |
| 
 | |
| struct a { };
 | |
| struct b : private a { }; // expected-note{{declared private here}}
 | |
|   
 | |
| class A {
 | |
|   virtual a* f(); // FIXME: desired-note{{overridden virtual function is here}}
 | |
| };
 | |
| 
 | |
| class B : A {
 | |
|   virtual b* f(); // expected-error{{invalid covariant return for virtual function: 'T3::a' is a private base class of 'T3::b'}}
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace T4 {
 | |
| 
 | |
| struct a { };
 | |
| struct a1 : a { };
 | |
| struct b : a, a1 { }; // expected-warning{{direct base 'T4::a' is inaccessible due to ambiguity:\n    struct T4::b -> struct T4::a\n    struct T4::b -> struct T4::a1 -> struct T4::a}}
 | |
|   
 | |
| class A {
 | |
|   virtual a* f(); // expected-note{{overridden virtual function is here}}
 | |
| };
 | |
| 
 | |
| class B : A {
 | |
|   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\
 | |
|     struct T4::b -> struct T4::a\n\
 | |
|     struct T4::b -> struct T4::a1 -> struct T4::a)}}
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace T5 {
 | |
|   
 | |
| struct a { };
 | |
| 
 | |
| class A {
 | |
|   virtual a* const f(); 
 | |
|   virtual a* const g(); // expected-note{{overridden virtual function is here}}
 | |
| };
 | |
| 
 | |
| class B : A {
 | |
|   virtual a* const f(); 
 | |
|   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')}}
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace T6 {
 | |
|   
 | |
| struct a { };
 | |
| 
 | |
| class A {
 | |
|   virtual const a* f(); 
 | |
|   virtual a* g(); // expected-note{{overridden virtual function is here}}
 | |
| };
 | |
| 
 | |
| class B : A {
 | |
|   virtual a* f(); 
 | |
|   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 *'}}
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace T7 {
 | |
|   struct a { };
 | |
|   struct b { };
 | |
| 
 | |
|   class A {
 | |
|     a* f();
 | |
|   };
 | |
| 
 | |
|   class B : A {
 | |
|     virtual b* f();
 | |
|   };
 | |
| }
 | |
| 
 | |
| namespace T8 {
 | |
|   struct a { };
 | |
|   struct b; // expected-note {{forward declaration of 'T8::b'}}
 | |
|   
 | |
|   class A {
 | |
|     virtual a *f();
 | |
|   };
 | |
|   
 | |
|   class B : A {
 | |
|     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)}}
 | |
|   };
 | |
| }
 | |
| 
 | |
| namespace T9 {
 | |
|   struct a { };
 | |
|   
 | |
|   template<typename T> struct b : a {
 | |
|     int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}}
 | |
|   };
 | |
|   
 | |
|   class A {
 | |
|     virtual a *f();
 | |
|   };
 | |
|   
 | |
|   class B : A {
 | |
|     virtual b<int> *f(); // expected-note {{in instantiation of template class 'T9::b<int>' requested here}}
 | |
|   };
 | |
| }
 | |
| 
 | |
| // PR5656
 | |
| class X0 {
 | |
|   virtual void f0();
 | |
| };
 | |
| class X1 : public X0 {
 | |
|   void f0() = 0;
 | |
| };
 | |
| 
 | |
| template <typename Base>
 | |
| struct Foo : Base { 
 | |
|   void f(int) = 0; // expected-error{{not virtual and cannot be declared pure}}
 | |
| };
 | |
| 
 | |
| struct Base1 { virtual void f(int); };
 | |
| struct Base2 { };
 | |
| 
 | |
| void test() {
 | |
|   (void)sizeof(Foo<Base1>);
 | |
|   (void)sizeof(Foo<Base2>); // expected-note{{instantiation}}
 | |
| }
 | |
| 
 | |
| template<typename Base>
 | |
| struct Foo2 : Base {
 | |
|   template<typename T> int f(T);
 | |
| };
 | |
| 
 | |
| void test2() {
 | |
|   Foo2<Base1> f1;
 | |
|   Foo2<Base2> f2;
 | |
|   f1.f(17);
 | |
|   f2.f(17);
 | |
| };
 | |
| 
 | |
| struct Foo3 {
 | |
|   virtual void f(int) = 0; // expected-note{{unimplemented pure virtual method}}
 | |
| };
 | |
| 
 | |
| template<typename T>
 | |
| struct Bar3 : Foo3 {
 | |
|   void f(T);
 | |
| };
 | |
| 
 | |
| void test3() {
 | |
|   Bar3<int> b3i; // okay
 | |
|   Bar3<float> b3f; // expected-error{{is an abstract class}}
 | |
| }
 | |
| 
 | |
| // 5920
 | |
| namespace PR5920 {
 | |
|   class Base {};
 | |
| 
 | |
|   template <typename T>
 | |
|   class Derived : public Base {};
 | |
| 
 | |
|   class Foo {
 | |
|    public:
 | |
|     virtual Base* Method();
 | |
|   };
 | |
| 
 | |
|   class Bar : public Foo {
 | |
|    public:
 | |
|     virtual Derived<int>* Method();
 | |
|   };
 | |
| }
 | |
| 
 | |
| // Look through template types and typedefs to see whether return types are
 | |
| // pointers or references.
 | |
| namespace PR6110 {
 | |
|   class Base {};
 | |
|   class Derived : public Base {};
 | |
| 
 | |
|   typedef Base* BaseP;
 | |
|   typedef Derived* DerivedP;
 | |
| 
 | |
|   class X { virtual BaseP f(); };
 | |
|   class X1 : public X { virtual DerivedP f(); };
 | |
| 
 | |
|   template <typename T> class Y { virtual T f(); };
 | |
|   template <typename T1, typename T> class Y1 : public Y<T> { virtual T1 f(); };
 | |
|   Y1<Derived*, Base*> y;
 | |
| }
 | |
| 
 | |
| // Defer checking for covariance if either return type is dependent.
 | |
| namespace type_dependent_covariance {
 | |
|   struct B {};
 | |
|   template <int N> struct TD : public B {};
 | |
|   template <> struct TD<1> {};
 | |
| 
 | |
|   template <int N> struct TB {};
 | |
|   struct D : public TB<0> {};
 | |
| 
 | |
|   template <int N> struct X {
 | |
|     virtual B* f1(); // expected-note{{overridden virtual function is here}}
 | |
|     virtual TB<N>* f2(); // expected-note{{overridden virtual function is here}}
 | |
|   };
 | |
|   template <int N, int M> struct X1 : X<N> {
 | |
|     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> *'}}
 | |
|     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> *')}}
 | |
|   };
 | |
| 
 | |
|   X1<0, 0> good;
 | |
|   X1<0, 1> bad_derived; // expected-note{{instantiation}}
 | |
|   X1<1, 0> bad_base; // expected-note{{instantiation}}
 | |
| }
 | |
| 
 | |
| namespace T10 {
 | |
|   struct A { };
 | |
|   struct B : A { };
 | |
| 
 | |
|   struct C { 
 | |
|     virtual A&& f();
 | |
|   };
 | |
| 
 | |
|   struct D : C {
 | |
|     virtual B&& f();
 | |
|   };
 | |
| };
 | |
| 
 | |
| namespace T11 {
 | |
|   struct A { };
 | |
|   struct B : A { };
 | |
| 
 | |
|   struct C { 
 | |
|     virtual A& f(); // expected-note {{overridden virtual function is here}}
 | |
|   };
 | |
| 
 | |
|   struct D : C {
 | |
|     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 &')}}
 | |
|   };
 | |
| };
 | |
| 
 | |
| namespace T12 {
 | |
|   struct A { };
 | |
|   struct B : A { };
 | |
| 
 | |
|   struct C { 
 | |
|     virtual A&& f(); // expected-note {{overridden virtual function is here}}
 | |
|   };
 | |
| 
 | |
|   struct D : C {
 | |
|     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 &&')}}
 | |
|   };
 | |
| };
 | |
| 
 | |
| namespace PR8168 {
 | |
|   class A {
 | |
|   public:
 | |
|     virtual void foo() {} // expected-note{{overridden virtual function is here}}
 | |
|   };
 | |
| 
 | |
|   class B : public A {
 | |
|   public:
 | |
|     static void foo() {} // expected-error{{'static' member function 'foo' overrides a virtual function}}
 | |
|   };
 | |
| }
 |