Skip to content

Commit 6d3df17

Browse files
committed
[Clang] Fix a crash when diagnosing wrong conversion to explicit object parameter
When an overload is invalid, we try to initialize each conversion sequence for the purpose of recovery, but we failed to initialized explicit objects, leading to a crash Fixes #147121
1 parent 1469c33 commit 6d3df17

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@ Bug Fixes to C++ Support
930930
- Fix a bug where private access specifier of overloaded function not respected. (#GH107629)
931931
- Correctly handles calling an explicit object member function template overload set
932932
through its address (``(&Foo::bar<baz>)()``).
933+
- Fix a crash when forming an invalid call to an operator with an explicit object member. (#GH147121)
933934
- Correctly handle allocations in the condition of a ``if constexpr``.(#GH120197) (#GH134820)
934935
- Fixed a crash when handling invalid member using-declaration in C++20+ mode. (#GH63254)
935936
- Fixed parsing of lambda expressions that appear after ``*`` or ``&`` in contexts where a declaration can appear. (#GH63880)

clang/lib/Sema/SemaOverload.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13131,7 +13131,8 @@ CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
1313113131
ParamTypes =
1313213132
Cand->Function->getType()->castAs<FunctionProtoType>()->getParamTypes();
1313313133
if (isa<CXXMethodDecl>(Cand->Function) &&
13134-
!isa<CXXConstructorDecl>(Cand->Function) && !Reversed) {
13134+
!isa<CXXConstructorDecl>(Cand->Function) && !Reversed &&
13135+
!Cand->Function->hasCXXExplicitFunctionObjectParameter()) {
1313513136
// Conversion 0 is 'this', which doesn't have a corresponding parameter.
1313613137
ConvIdx = 1;
1313713138
if (CSK == OverloadCandidateSet::CSK_Operator &&
@@ -13149,9 +13150,8 @@ CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
1314913150

1315013151
// Fill in the rest of the conversions.
1315113152
for (unsigned ParamIdx = Reversed ? ParamTypes.size() - 1 : 0;
13152-
ConvIdx != ConvCount;
13153+
ConvIdx != ConvCount && ArgIdx < Args.size();
1315313154
++ConvIdx, ++ArgIdx, ParamIdx += (Reversed ? -1 : 1)) {
13154-
assert(ArgIdx < Args.size() && "no argument for this arg conversion");
1315513155
if (Cand->Conversions[ConvIdx].isInitialized()) {
1315613156
// We've already checked this conversion.
1315713157
} else if (ParamIdx < ParamTypes.size()) {

clang/test/SemaCXX/cxx2b-deducing-this.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,3 +1290,60 @@ void f() {
12901290

12911291

12921292
}
1293+
1294+
namespace GH147121 {
1295+
struct X {};
1296+
struct S1 {
1297+
bool operator==(this auto &&, const X &); // #S1-cand
1298+
};
1299+
struct S2 {
1300+
bool operator==(this X, const auto &&); // #S2-cand
1301+
};
1302+
1303+
struct S3 {
1304+
S3& operator++(this X); // #S3-inc-cand
1305+
S3& operator++(this int); // #S3-inc-cand
1306+
int operator[](this X); // #S3-sub-cand
1307+
int operator[](this int); // #S3-sub-cand2
1308+
void f(this X); // #S3-f-cand
1309+
void f(this int); // #S3-f-cand2
1310+
};
1311+
1312+
int main() {
1313+
S1{} == S1{};
1314+
// expected-error@-1 {{invalid operands to binary expression ('S1' and 'S1')}}
1315+
// expected-note@#S1-cand {{candidate function template not viable}}
1316+
// expected-note@#S1-cand {{candidate function (with reversed parameter order) template not viable}}
1317+
1318+
1319+
S1{} != S1{};
1320+
// expected-error@-1 {{invalid operands to binary expression ('S1' and 'S1')}}
1321+
// expected-note@#S1-cand {{candidate function template not viable}}
1322+
// expected-note@#S1-cand {{candidate function (with reversed parameter order) template not viable}}
1323+
1324+
1325+
S2{} == S2{};
1326+
// expected-error@-1 {{invalid operands to binary expression ('S2' and 'S2')}}
1327+
// expected-note@#S2-cand {{candidate function template not viable}}
1328+
// expected-note@#S2-cand {{candidate function (with reversed parameter order) template not viable}}
1329+
1330+
1331+
S2{} != S2{};
1332+
// expected-error@-1 {{invalid operands to binary expression ('S2' and 'S2')}}
1333+
// expected-note@#S2-cand {{candidate function template not viable}}
1334+
// expected-note@#S2-cand {{candidate function (with reversed parameter order) template not viable}}
1335+
1336+
S3 s3;
1337+
++s3;
1338+
// expected-error@-1{{cannot increment value of type 'S3'}}
1339+
s3[];
1340+
// expected-error@-1{{no viable overloaded operator[] for type 'S3'}}
1341+
// expected-note@#S3-sub-cand {{candidate function not viable: no known conversion from 'S3' to 'X' for object argument}}
1342+
// expected-note@#S3-sub-cand2 {{candidate function not viable: no known conversion from 'S3' to 'int' for object argument}}
1343+
1344+
s3.f();
1345+
// expected-error@-1{{no matching member function for call to 'f'}}
1346+
// expected-note@#S3-f-cand {{candidate function not viable: no known conversion from 'S3' to 'X' for object argument}}
1347+
// expected-note@#S3-f-cand2 {{candidate function not viable: no known conversion from 'S3' to 'int' for object argument}}
1348+
}
1349+
}

0 commit comments

Comments
 (0)