Better diagnostics for covariance when checking overriding return types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71786 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index c1b95cc..1a917fe 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify %s
+// RUN: clang-cc -fsyntax-only -faccess-control -verify %s
namespace T1 {
@@ -11,3 +11,83 @@
};
}
+
+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 overrrides ('struct T2::b *' is not derived from 'struct T2::a *')}}
+};
+
+}
+
+namespace T3 {
+
+struct a { };
+struct b : private a { }; // expected-note{{'private' inheritance specifier here}}
+
+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 (conversion from 'struct T3::b' to inaccessible base class 'struct T3::a')}}
+};
+
+}
+
+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 'struct T4::b' to base class 'struct 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 ('struct T5::a *' has different qualifiers than 'struct 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 'struct T6::a const *' is more qualified than class type 'struct T6::a *'}}
+};
+
+}