summaryrefslogtreecommitdiff
path: root/clang/test/SemaCXX/virtual-override.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX/virtual-override.cpp')
-rw-r--r--clang/test/SemaCXX/virtual-override.cpp290
1 files changed, 290 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/virtual-override.cpp b/clang/test/SemaCXX/virtual-override.cpp
new file mode 100644
index 0000000..b477438
--- /dev/null
+++ b/clang/test/SemaCXX/virtual-override.cpp
@@ -0,0 +1,290 @@
+// RUN: %clang_cc1 -fsyntax-only -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 { };
+
+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}}
+ };
+}