Author: Boaz Brickner Date: 2024-10-16T16:02:25+02:00 New Revision: b333edd0d6da744c099ad3ff3b5fbd2d4e4dd45a
URL: https://github.com/llvm/llvm-project/commit/b333edd0d6da744c099ad3ff3b5fbd2d4e4dd45a DIFF: https://github.com/llvm/llvm-project/commit/b333edd0d6da744c099ad3ff3b5fbd2d4e4dd45a.diff LOG: [clang] When checking for covariant return types, make sure the pointers or references are to *classes* (#111856) https://eel.is/c++draft/class.virtual#8.1 This prevents overriding methods with non class return types that have less cv-qualification. Fixes: #111742 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaDeclCXX.cpp clang/test/SemaCXX/virtual-override.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 33eb9a2b5804a0..dc5564b6db119f 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; + }; + - The warning ``-Wdeprecated-literal-operator`` is now on by default, as this is something that WG21 has shown interest in removing from the language. The result is that anyone who is compiling with ``-Werror`` should see this diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 75d82c12e0c1f3..38f808a470aa87 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_ diff erent_return_type_for_overriding_virtual_function) << New->getDeclName() << NewTy << OldTy diff --git a/clang/test/SemaCXX/virtual-override.cpp b/clang/test/SemaCXX/virtual-override.cpp index 72abfc3cf51e1f..d37c275d46baeb 100644 --- a/clang/test/SemaCXX/virtual-override.cpp +++ b/clang/test/SemaCXX/virtual-override.cpp @@ -19,10 +19,12 @@ struct b { }; class A { virtual a* f(); // expected-note{{overridden virtual function is here}} + virtual int *g(); // 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 ('b *' is not derived from 'a *')}} + virtual char *g(); // expected-error{{virtual function 'g' has a diff erent return type ('char *') than the function it overrides (which has return type 'int *')}} }; } @@ -83,11 +85,15 @@ struct a { }; class A { virtual const a* f(); virtual a* g(); // expected-note{{overridden virtual function is here}} + virtual const int* h(); // expected-note{{overridden virtual function is here}} + virtual int* i(); // 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 a *' is more qualified than class type 'a *'}} + virtual int* h(); // expected-error{{virtual function 'h' has a diff erent return type ('int *') than the function it overrides (which has return type 'const int *')}} + virtual const int* i(); // expected-error{{virtual function 'i' has a diff erent 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