https://github.com/bricknerb updated https://github.com/llvm/llvm-project/pull/112853
>From b1ffbf6b7a59d1e57dccf8b9fab32c2c7d599058 Mon Sep 17 00:00:00 2001 From: Boaz Brickner <brick...@google.com> Date: Mon, 21 Oct 2024 13:07:37 +0200 Subject: [PATCH 1/2] [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. --- clang/test/SemaCXX/virtual-override.cpp | 28 +++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/clang/test/SemaCXX/virtual-override.cpp b/clang/test/SemaCXX/virtual-override.cpp index ce6dd35e0b56fa..fc2a36937d4b5d 100644 --- a/clang/test/SemaCXX/virtual-override.cpp +++ b/clang/test/SemaCXX/virtual-override.cpp @@ -83,7 +83,7 @@ namespace T6 { struct a { }; class A { - // Classes. + // Check cv-qualification. virtual const a* const_vs_unqualified_class(); virtual a* unqualified_vs_const_class(); // expected-note{{overridden virtual function is here}} @@ -102,13 +102,23 @@ class A { virtual const volatile a* const_volatile_vs_unualified_class(); virtual a* unqualified_vs_const_volatile_class(); // expected-note{{overridden virtual function is here}} - // Non Classes. + // Check lvalue ref vs rvalue ref vs pointer. + virtual a& rvalue_ref(); + virtual a&& lvalue_ref(); + virtual a& rvalue_vs_lvalue_ref(); // expected-note{{overridden virtual function is here}} + virtual a&& lvalue_vs_rvalue_ref(); // expected-note{{overridden virtual function is here}} + virtual a& rvalue_ref_vs_pointer(); // expected-note{{overridden virtual function is here}} + virtual a* pointer_vs_rvalue_ref(); // expected-note{{overridden virtual function is here}} + virtual a&& lvalue_ref_vs_pointer(); // expected-note{{overridden virtual function is here}} + virtual a* pointer_vs_lvalue_ref(); // expected-note{{overridden virtual function is here}} + + // Check non class. virtual const int* const_vs_unqualified_non_class(); // expected-note{{overridden virtual function is here}} virtual int* unqualified_vs_const_non_class(); // expected-note{{overridden virtual function is here}} }; class B : A { - // Classes. + // Check cv-qualification. a* const_vs_unqualified_class() override; 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 *')}} @@ -127,7 +137,17 @@ class B : A { a* const_volatile_vs_unualified_class() override; 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 *')}} - // Non Classes. + // Check lvalue ref vs rvalue ref vs pointer. + a& rvalue_ref() override; + a&& lvalue_ref() override; + 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 &')}} + 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 &&')}} + 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 &')}} + 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 *')}} + 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 &&')}} + 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 *')}} + + // Check non class. 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 *')}} 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 *')}} }; >From b4221ce300697bf429278222a3f61f9498b5f5ae Mon Sep 17 00:00:00 2001 From: Boaz Brickner <brick...@google.com> Date: Mon, 21 Oct 2024 14:21:14 +0200 Subject: [PATCH 2/2] [clang] Move the tests for https://cplusplus.github.io/CWG/issues/960.html to clang/test/CXX/drs/cwg9xx.cpp. --- clang/test/CXX/drs/cwg9xx.cpp | 32 +++++++++++++++++++++++++ clang/test/SemaCXX/virtual-override.cpp | 20 ---------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/clang/test/CXX/drs/cwg9xx.cpp b/clang/test/CXX/drs/cwg9xx.cpp index 2700b0f5662a2c..7e8fb48f110317 100644 --- a/clang/test/CXX/drs/cwg9xx.cpp +++ b/clang/test/CXX/drs/cwg9xx.cpp @@ -93,6 +93,38 @@ struct B : A { } // namespace example2 } // namespace cwg952 +namespace cwg960 { // cwg960: 2.8 +struct a {}; +class A { +#if __cplusplus >= 201103L + // Check lvalue ref vs rvalue ref vs pointer. + virtual a& rvalue_ref(); + virtual a&& lvalue_ref(); + virtual a& rvalue_vs_lvalue_ref(); // expected-note{{overridden virtual function is here}} + virtual a&& lvalue_vs_rvalue_ref(); // expected-note{{overridden virtual function is here}} + virtual a& rvalue_ref_vs_pointer(); // expected-note{{overridden virtual function is here}} + virtual a* pointer_vs_rvalue_ref(); // expected-note{{overridden virtual function is here}} + virtual a&& lvalue_ref_vs_pointer(); // expected-note{{overridden virtual function is here}} + virtual a* pointer_vs_lvalue_ref(); // expected-note{{overridden virtual function is here}} +#endif +}; + +class B : A { +#if __cplusplus >= 201103L + // Check lvalue ref vs rvalue ref vs pointer. + a& rvalue_ref() override; + a&& lvalue_ref() override; + 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 &')}} + 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 &&')}} + 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 &')}} + 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 *')}} + 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 &&')}} + 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 *')}} +#endif +}; + +} // namespace cwg960 + namespace cwg974 { // cwg974: yes #if __cplusplus >= 201103L void test() { diff --git a/clang/test/SemaCXX/virtual-override.cpp b/clang/test/SemaCXX/virtual-override.cpp index fc2a36937d4b5d..c8cd4c6a29e2d5 100644 --- a/clang/test/SemaCXX/virtual-override.cpp +++ b/clang/test/SemaCXX/virtual-override.cpp @@ -102,16 +102,6 @@ class A { virtual const volatile a* const_volatile_vs_unualified_class(); virtual a* unqualified_vs_const_volatile_class(); // expected-note{{overridden virtual function is here}} - // Check lvalue ref vs rvalue ref vs pointer. - virtual a& rvalue_ref(); - virtual a&& lvalue_ref(); - virtual a& rvalue_vs_lvalue_ref(); // expected-note{{overridden virtual function is here}} - virtual a&& lvalue_vs_rvalue_ref(); // expected-note{{overridden virtual function is here}} - virtual a& rvalue_ref_vs_pointer(); // expected-note{{overridden virtual function is here}} - virtual a* pointer_vs_rvalue_ref(); // expected-note{{overridden virtual function is here}} - virtual a&& lvalue_ref_vs_pointer(); // expected-note{{overridden virtual function is here}} - virtual a* pointer_vs_lvalue_ref(); // expected-note{{overridden virtual function is here}} - // Check non class. virtual const int* const_vs_unqualified_non_class(); // expected-note{{overridden virtual function is here}} virtual int* unqualified_vs_const_non_class(); // expected-note{{overridden virtual function is here}} @@ -137,16 +127,6 @@ class B : A { a* const_volatile_vs_unualified_class() override; 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 *')}} - // Check lvalue ref vs rvalue ref vs pointer. - a& rvalue_ref() override; - a&& lvalue_ref() override; - 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 &')}} - 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 &&')}} - 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 &')}} - 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 *')}} - 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 &&')}} - 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 *')}} - // Check non class. 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 *')}} 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 *')}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits