[clang] [clang] When checking for covariant return types, make sure the poiners or references are to *classes* (PR #111856)
Boaz Brickner via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 11 06:38:55 PDT 2024
https://github.com/bricknerb updated https://github.com/llvm/llvm-project/pull/111856
>From 786d31e2657964e578cd1fdf2006b0fb3b19fab6 Mon Sep 17 00:00:00 2001
From: Boaz Brickner <brickner at google.com>
Date: Thu, 10 Oct 2024 15:15:23 +0000
Subject: [PATCH 1/4] [clang] When checking for covariant return types, make
sure the pointers or references are to *classes*.
https://eel.is/c++draft/class.virtual#8.1
This prevents overriding methods with non class return types that have less cv-qualification.
---
clang/lib/Sema/SemaDeclCXX.cpp | 4 ++--
clang/test/SemaCXX/virtual-override.cpp | 10 ++++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 9cb2ed02a3f764..6195b62b8afa16 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18273,7 +18273,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
}
// The return types aren't either both pointers or references to a class type.
- if (NewClassTy.isNull()) {
+ if (NewClassTy.isNull() || !NewClassTy->isStructureOrClassType()) {
Diag(New->getLocation(),
diag::err_different_return_type_for_overriding_virtual_function)
<< New->getDeclName() << NewTy << OldTy
@@ -18296,7 +18296,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
diag::err_covariant_return_incomplete,
New->getDeclName()))
return true;
- }
+ }
// Check if the new class derives from the old class.
if (!IsDerivedFrom(New->getLocation(), NewClassTy, OldClassTy)) {
diff --git a/clang/test/SemaCXX/virtual-override.cpp b/clang/test/SemaCXX/virtual-override.cpp
index 72abfc3cf51e1f..6008b8ed063f20 100644
--- a/clang/test/SemaCXX/virtual-override.cpp
+++ b/clang/test/SemaCXX/virtual-override.cpp
@@ -289,3 +289,13 @@ namespace PR8168 {
static void foo() {} // expected-error{{'static' member function 'foo' overrides a virtual function}}
};
}
+
+namespace T13 {
+ struct A {
+ virtual const int *f() const; // expected-note{{overridden virtual function is here}}
+ };
+
+ struct B : A {
+ int *f() const override; // expected-error{{virtual function 'f' has a different return type ('int *') than the function it overrides (which has return type 'const int *')}}
+ };
+}
>From 027a985f2ca2bbe007db751af4fdbb5d8f12959d Mon Sep 17 00:00:00 2001
From: Boaz Brickner <brickner at google.com>
Date: Fri, 11 Oct 2024 05:29:05 +0000
Subject: [PATCH 2/4] Fix indentation.
---
clang/lib/Sema/SemaDeclCXX.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 6195b62b8afa16..75d010dc4e04d8 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18296,7 +18296,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
diag::err_covariant_return_incomplete,
New->getDeclName()))
return true;
- }
+ }
// Check if the new class derives from the old class.
if (!IsDerivedFrom(New->getLocation(), NewClassTy, OldClassTy)) {
>From 0b0452f3b7206fdea595aff684c329fd4563f631 Mon Sep 17 00:00:00 2001
From: Boaz Brickner <brickner at google.com>
Date: Fri, 11 Oct 2024 12:27:00 +0000
Subject: [PATCH 3/4] [clang] Add the breaking change to more correctly check
covariance when return type doesn't point to a class to release notes.
---
clang/docs/ReleaseNotes.rst | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index df165b91252505..55ca61955c5b01 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -99,6 +99,19 @@ C++ Specific Potentially Breaking Changes
// Was error, now evaluates to false.
constexpr bool b = f() == g();
+- Clang will now correctly not consider pointers to non classes for covariance.
+
+ .. code-block:: c++
+
+ struct A {
+ virtual const int *f() const;
+ };
+ struct B : A {
+ // Return type has less cv-qualification but doesn't point to a class.
+ // Error will be generated.
+ int *f() const override;
+ };
+
ABI Changes in This Version
---------------------------
>From d5cf39d317ea2474477382f6dfa3a116c7db67f8 Mon Sep 17 00:00:00 2001
From: Boaz Brickner <brickner at google.com>
Date: Fri, 11 Oct 2024 13:38:39 +0000
Subject: [PATCH 4/4] [clang] Fix code indentation in release notes for fixing
how we handle pointers to non classes when calculating covariance.
---
clang/docs/ReleaseNotes.rst | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 55ca61955c5b01..3ae716859fdcdf 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -103,14 +103,14 @@ C++ Specific Potentially Breaking Changes
.. code-block:: c++
- struct A {
- virtual const int *f() const;
- };
- struct B : A {
- // Return type has less cv-qualification but doesn't point to a class.
- // Error will be generated.
- int *f() const override;
- };
+ struct A {
+ virtual const int *f() const;
+ };
+ struct B : A {
+ // Return type has less cv-qualification but doesn't point to a class.
+ // Error will be generated.
+ int *f() const override;
+ };
ABI Changes in This Version
---------------------------
More information about the cfe-commits
mailing list