https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/110435
>From c52634882631a71fad956a70179b480abf13006a Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Sun, 29 Sep 2024 22:01:38 +0300 Subject: [PATCH 1/3] [Clang] fix overload resolution for object parameters with top-level cv-qualifiers in member functions --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaOverload.cpp | 3 +++ clang/test/SemaCXX/cxx2b-deducing-this.cpp | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 28c759538f7df6..1bec2838765dab 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -447,6 +447,7 @@ Bug Fixes to C++ Support - Fixed an assertion failure in debug mode, and potential crashes in release mode, when diagnosing a failed cast caused indirectly by a failed implicit conversion to the type of the constructor parameter. - Fixed an assertion failure by adjusting integral to boolean vector conversions (#GH108326) +- 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 0c1e054f7c30a4..7c40bab70bbe9d 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1511,6 +1511,9 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, auto NewObjectType = New->getFunctionObjectParameterReferenceType(); auto OldObjectType = Old->getFunctionObjectParameterReferenceType(); + if (NewObjectType.isConstQualified() != OldObjectType.isConstQualified()) + return false; + auto IsImplicitWithNoRefQual = [](const CXXMethodDecl *F) { return F->getRefQualifier() == RQ_None && !F->isExplicitObjectMemberFunction(); diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index 63bf92e8d5edd3..5fd02502ce6df4 100644 --- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp +++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp @@ -1073,3 +1073,10 @@ int main() { return foo[]; // expected-error {{no viable overloaded operator[] for type 'Foo'}} } } + +namespace GH100394 { +struct C { + void f(this const C); + void f() const ; // ok +}; +} >From d377c01f46acf28f1dc74103c6a26df6c0c2e376 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Sun, 6 Oct 2024 11:52:48 +0300 Subject: [PATCH 2/3] adjust overload resolution for volatile qualifiers --- clang/lib/Sema/SemaOverload.cpp | 7 +++++-- clang/test/SemaCXX/cxx2b-deducing-this.cpp | 12 +++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 7c40bab70bbe9d..56705971517cc3 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1511,8 +1511,11 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, auto NewObjectType = New->getFunctionObjectParameterReferenceType(); auto OldObjectType = Old->getFunctionObjectParameterReferenceType(); - if (NewObjectType.isConstQualified() != OldObjectType.isConstQualified()) - return false; + if (Old->isExplicitObjectMemberFunction() && + OldObjectType.getQualifiers() != NewObjectType.getQualifiers()) + return OldObjectType.isConstQualified() && + (NewObjectType.isConstQualified() || + NewObjectType.isVolatileQualified()); auto IsImplicitWithNoRefQual = [](const CXXMethodDecl *F) { return F->getRefQualifier() == RQ_None && diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index 5fd02502ce6df4..7dcd63a587c708 100644 --- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp +++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp @@ -1075,8 +1075,14 @@ int main() { } namespace GH100394 { -struct C { - void f(this const C); - void f() const ; // ok +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}} }; } >From d524f7c0556fa08bd93a48f1ac6edd754a12926a Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Wed, 9 Oct 2024 02:46:48 +0300 Subject: [PATCH 3/3] adjust qualifier restrictions for overriding explicit object members --- clang/lib/Sema/SemaOverload.cpp | 31 ++++++++++++++-------- clang/test/SemaCXX/cxx2b-deducing-this.cpp | 21 +++++++++++---- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 95db7a4305cc87..c1799dfd2bc163 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1422,8 +1422,14 @@ 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()) { + if (M->getNumParams() > 0) { + auto ThisType = M->getParamDecl(0)->getType().getCanonicalType(); + if (ThisType.isConstQualified()) + Q.removeConst(); + } return Q; + } // We do not allow overloading based off of '__restrict'. Q.removeRestrict(); @@ -1439,14 +1445,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() && @@ -1511,12 +1526,6 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, auto NewObjectType = New->getFunctionObjectParameterReferenceType(); auto OldObjectType = Old->getFunctionObjectParameterReferenceType(); - if (Old->isExplicitObjectMemberFunction() && - OldObjectType.getQualifiers() != NewObjectType.getQualifiers()) - return OldObjectType.isConstQualified() && - (NewObjectType.isConstQualified() || - NewObjectType.isVolatileQualified()); - auto IsImplicitWithNoRefQual = [](const CXXMethodDecl *F) { return F->getRefQualifier() == RQ_None && !F->isExplicitObjectMemberFunction(); diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index 7dcd63a587c708..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}} }; @@ -1085,4 +1084,16 @@ struct C2 { 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