Author: Oleksandr T. Date: 2024-10-12T10:11:36+02:00 New Revision: 3292ce08678ded1509f078d7de4753a461fc3ff8
URL: https://github.com/llvm/llvm-project/commit/3292ce08678ded1509f078d7de4753a461fc3ff8 DIFF: https://github.com/llvm/llvm-project/commit/3292ce08678ded1509f078d7de4753a461fc3ff8.diff LOG: [Clang] fix overload resolution for object parameters with top-level cv-qualifiers in member functions (#110435) Fixes #100394 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaOverload.cpp clang/test/SemaCXX/cxx2b-deducing-this.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 337e3fc10bf49d..202c3ee98ed2be 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -512,6 +512,7 @@ Bug Fixes to C++ Support and undeclared templates. (#GH107047, #GH49093) - Clang no longer crashes when a lambda contains an invalid block declaration that contains an unexpanded parameter pack. (#GH109148) +- Fixed overload handling for object parameters with top-level cv-qualifiers in explicit member functions (#GH100394) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 2cde8131108fbe..1205e85b4e6f53 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1422,8 +1422,12 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, // the implicit object parameter are of the same type. auto NormalizeQualifiers = [&](const CXXMethodDecl *M, Qualifiers Q) { - if (M->isExplicitObjectMemberFunction()) + if (M->isExplicitObjectMemberFunction()) { + auto ThisType = M->getFunctionObjectParameterReferenceType(); + if (ThisType.isConstQualified()) + Q.removeConst(); return Q; + } // We do not allow overloading based off of '__restrict'. Q.removeRestrict(); @@ -1439,14 +1443,23 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, return Q; }; - auto CompareType = [&](QualType Base, QualType D) { - auto BS = Base.getNonReferenceType().getCanonicalType().split(); + auto AreQualifiersEqual = [&](SplitQualType BS, SplitQualType DS) { BS.Quals = NormalizeQualifiers(OldMethod, BS.Quals); + DS.Quals = NormalizeQualifiers(NewMethod, DS.Quals); + + if (OldMethod->isExplicitObjectMemberFunction()) { + BS.Quals.removeVolatile(); + DS.Quals.removeVolatile(); + } + return BS.Quals == DS.Quals; + }; + + auto CompareType = [&](QualType Base, QualType D) { + auto BS = Base.getNonReferenceType().getCanonicalType().split(); auto DS = D.getNonReferenceType().getCanonicalType().split(); - DS.Quals = NormalizeQualifiers(NewMethod, DS.Quals); - if (BS.Quals != DS.Quals) + if (!AreQualifiersEqual(BS, DS)) return false; if (OldMethod->isImplicitObjectMemberFunction() && diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index 63bf92e8d5edd3..2a984a75f37d21 100644 --- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp +++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp @@ -142,8 +142,8 @@ struct Corresponding { void d(this Corresponding&&); void d(this const Corresponding&); void d(this const int&); - void d(this const int); - void d(this int); + void d(this const int); // expected-note {{previous declaration is here}} + void d(this int); // expected-error {{class member cannot be redeclared}} void e(this const Corresponding&&); // expected-note {{here}} void e() const &&; // expected-error{{cannot be redeclared}} @@ -171,9 +171,8 @@ struct CorrespondingTpl { void d(this Corresponding&&); void d(this const Corresponding&); void d(this const int&); - void d(this const int); - void d(this int); - + void d(this const int); // expected-note {{previous declaration is here}} + void d(this int); // expected-error {{class member cannot be redeclared}} void e(this const CorrespondingTpl&&); // expected-note {{here}} void e() const &&; // expected-error{{cannot be redeclared}} }; @@ -1073,3 +1072,28 @@ int main() { return foo[]; // expected-error {{no viable overloaded operator[] for type 'Foo'}} } } + +namespace GH100394 { +struct C1 { + void f(this const C1); + void f() const; // ok +}; + +struct C2 { + void f(this const C2); // expected-note {{previous declaration is here}} + void f(this volatile C2); // expected-error {{class member cannot be redeclared}} \ + // expected-warning {{volatile-qualified parameter type 'volatile C2' is deprecated}} +}; + +struct C3 { + void f(this volatile C3); // expected-note {{previous declaration is here}} \ + // expected-warning {{volatile-qualified parameter type 'volatile C3' is deprecated}} + void f(this const C3); // expected-error {{class member cannot be redeclared}} +}; + +struct C4 { + void f(this const C4); // expected-note {{previous declaration is here}} + void f(this const volatile C4); // expected-error {{class member cannot be redeclared}} \ + // expected-warning {{volatile-qualified parameter type 'const volatile C4' is deprecated}} +}; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits