Skip to content

Commit b1ffbf6

Browse files
committed
[clang] Add covariance tests that make sure we return an error when return value is different in pointer / lvalue ref / rvalue ref
Per https://cplusplus.github.io/CWG/issues/960.html.
1 parent a18dd29 commit b1ffbf6

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

clang/test/SemaCXX/virtual-override.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ namespace T6 {
8383
struct a { };
8484

8585
class A {
86-
// Classes.
86+
// Check cv-qualification.
8787
virtual const a* const_vs_unqualified_class();
8888
virtual a* unqualified_vs_const_class(); // expected-note{{overridden virtual function is here}}
8989

@@ -102,13 +102,23 @@ class A {
102102
virtual const volatile a* const_volatile_vs_unualified_class();
103103
virtual a* unqualified_vs_const_volatile_class(); // expected-note{{overridden virtual function is here}}
104104

105-
// Non Classes.
105+
// Check lvalue ref vs rvalue ref vs pointer.
106+
virtual a& rvalue_ref();
107+
virtual a&& lvalue_ref();
108+
virtual a& rvalue_vs_lvalue_ref(); // expected-note{{overridden virtual function is here}}
109+
virtual a&& lvalue_vs_rvalue_ref(); // expected-note{{overridden virtual function is here}}
110+
virtual a& rvalue_ref_vs_pointer(); // expected-note{{overridden virtual function is here}}
111+
virtual a* pointer_vs_rvalue_ref(); // expected-note{{overridden virtual function is here}}
112+
virtual a&& lvalue_ref_vs_pointer(); // expected-note{{overridden virtual function is here}}
113+
virtual a* pointer_vs_lvalue_ref(); // expected-note{{overridden virtual function is here}}
114+
115+
// Check non class.
106116
virtual const int* const_vs_unqualified_non_class(); // expected-note{{overridden virtual function is here}}
107117
virtual int* unqualified_vs_const_non_class(); // expected-note{{overridden virtual function is here}}
108118
};
109119

110120
class B : A {
111-
// Classes.
121+
// Check cv-qualification.
112122
a* const_vs_unqualified_class() override;
113123
const a* unqualified_vs_const_class() override; // expected-error{{return type of virtual function 'unqualified_vs_const_class' is not covariant with the return type of the function it overrides (class type 'const a *' does not have the same cv-qualification as or less cv-qualification than class type 'a *')}}
114124

@@ -127,7 +137,17 @@ class B : A {
127137
a* const_volatile_vs_unualified_class() override;
128138
const volatile a* unqualified_vs_const_volatile_class() override; // expected-error{{return type of virtual function 'unqualified_vs_const_volatile_class' is not covariant with the return type of the function it overrides (class type 'const volatile a *' does not have the same cv-qualification as or less cv-qualification than class type 'a *')}}
129139

130-
// Non Classes.
140+
// Check lvalue ref vs rvalue ref vs pointer.
141+
a& rvalue_ref() override;
142+
a&& lvalue_ref() override;
143+
a&& rvalue_vs_lvalue_ref() override; // expected-error{{virtual function 'rvalue_vs_lvalue_ref' has a different return type ('a &&') than the function it overrides (which has return type 'a &')}}
144+
a& lvalue_vs_rvalue_ref() override; // expected-error{{virtual function 'lvalue_vs_rvalue_ref' has a different return type ('a &') than the function it overrides (which has return type 'a &&')}}
145+
a* rvalue_ref_vs_pointer() override; // expected-error{{virtual function 'rvalue_ref_vs_pointer' has a different return type ('a *') than the function it overrides (which has return type 'a &')}}
146+
a& pointer_vs_rvalue_ref() override; // expected-error{{virtual function 'pointer_vs_rvalue_ref' has a different return type ('a &') than the function it overrides (which has return type 'a *')}}
147+
a* lvalue_ref_vs_pointer() override; // expected-error{{virtual function 'lvalue_ref_vs_pointer' has a different return type ('a *') than the function it overrides (which has return type 'a &&')}}
148+
a&& pointer_vs_lvalue_ref() override; // expected-error{{virtual function 'pointer_vs_lvalue_ref' has a different return type ('a &&') than the function it overrides (which has return type 'a *')}}
149+
150+
// Check non class.
131151
int* const_vs_unqualified_non_class() override; // expected-error{{virtual function 'const_vs_unqualified_non_class' has a different return type ('int *') than the function it overrides (which has return type 'const int *')}}
132152
const int* unqualified_vs_const_non_class() override; // expected-error{{virtual function 'unqualified_vs_const_non_class' has a different return type ('const int *') than the function it overrides (which has return type 'int *')}}
133153
};

0 commit comments

Comments
 (0)