Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,7 @@ Bug Fixes to C++ Support
- Fix a bug where private access specifier of overloaded function not respected. (#GH107629)
- Correctly handles calling an explicit object member function template overload set
through its address (``(&Foo::bar<baz>)()``).
- Fix a crash when forming an invalid call to an operator with an explicit object member. (#GH147121)
- Correctly handle allocations in the condition of a ``if constexpr``.(#GH120197) (#GH134820)
- Fixed a crash when handling invalid member using-declaration in C++20+ mode. (#GH63254)
- Fixed parsing of lambda expressions that appear after ``*`` or ``&`` in contexts where a declaration can appear. (#GH63880)
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13131,7 +13131,8 @@ CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
ParamTypes =
Cand->Function->getType()->castAs<FunctionProtoType>()->getParamTypes();
if (isa<CXXMethodDecl>(Cand->Function) &&
!isa<CXXConstructorDecl>(Cand->Function) && !Reversed) {
!isa<CXXConstructorDecl>(Cand->Function) && !Reversed &&
!Cand->Function->hasCXXExplicitFunctionObjectParameter()) {
// Conversion 0 is 'this', which doesn't have a corresponding parameter.
ConvIdx = 1;
if (CSK == OverloadCandidateSet::CSK_Operator &&
Expand All @@ -13149,9 +13150,8 @@ CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,

// Fill in the rest of the conversions.
for (unsigned ParamIdx = Reversed ? ParamTypes.size() - 1 : 0;
ConvIdx != ConvCount;
ConvIdx != ConvCount && ArgIdx < Args.size();
++ConvIdx, ++ArgIdx, ParamIdx += (Reversed ? -1 : 1)) {
assert(ArgIdx < Args.size() && "no argument for this arg conversion");
if (Cand->Conversions[ConvIdx].isInitialized()) {
// We've already checked this conversion.
} else if (ParamIdx < ParamTypes.size()) {
Expand Down
57 changes: 57 additions & 0 deletions clang/test/SemaCXX/cxx2b-deducing-this.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1290,3 +1290,60 @@ void f() {


}

namespace GH147121 {
struct X {};
struct S1 {
bool operator==(this auto &&, const X &); // #S1-cand
};
struct S2 {
bool operator==(this X, const auto &&); // #S2-cand
};

struct S3 {
S3& operator++(this X); // #S3-inc-cand
S3& operator++(this int); // #S3-inc-cand
int operator[](this X); // #S3-sub-cand
int operator[](this int); // #S3-sub-cand2
void f(this X); // #S3-f-cand
void f(this int); // #S3-f-cand2
};

int main() {
S1{} == S1{};
// expected-error@-1 {{invalid operands to binary expression ('S1' and 'S1')}}
// expected-note@#S1-cand {{candidate function template not viable}}
// expected-note@#S1-cand {{candidate function (with reversed parameter order) template not viable}}


S1{} != S1{};
// expected-error@-1 {{invalid operands to binary expression ('S1' and 'S1')}}
// expected-note@#S1-cand {{candidate function template not viable}}
// expected-note@#S1-cand {{candidate function (with reversed parameter order) template not viable}}


S2{} == S2{};
// expected-error@-1 {{invalid operands to binary expression ('S2' and 'S2')}}
// expected-note@#S2-cand {{candidate function template not viable}}
// expected-note@#S2-cand {{candidate function (with reversed parameter order) template not viable}}


S2{} != S2{};
// expected-error@-1 {{invalid operands to binary expression ('S2' and 'S2')}}
// expected-note@#S2-cand {{candidate function template not viable}}
// expected-note@#S2-cand {{candidate function (with reversed parameter order) template not viable}}

S3 s3;
++s3;
// expected-error@-1{{cannot increment value of type 'S3'}}
s3[];
// expected-error@-1{{no viable overloaded operator[] for type 'S3'}}
// expected-note@#S3-sub-cand {{candidate function not viable: no known conversion from 'S3' to 'X' for object argument}}
// expected-note@#S3-sub-cand2 {{candidate function not viable: no known conversion from 'S3' to 'int' for object argument}}

s3.f();
// expected-error@-1{{no matching member function for call to 'f'}}
// expected-note@#S3-f-cand {{candidate function not viable: no known conversion from 'S3' to 'X' for object argument}}
// expected-note@#S3-f-cand2 {{candidate function not viable: no known conversion from 'S3' to 'int' for object argument}}
}
}
Loading