Skip to content

Commit ab0d11c

Browse files
authored
[Clang] Fix a crash when diagnosing wrong conversion to explicit object parameter (#147996)
When an overload is invalid, we try to initialize each conversion sequence for the purpose of diagmostics, but we failed to initialize explicit objects, leading to a crash Fixes #147121
1 parent d93cc7a commit ab0d11c

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
@@ -932,6 +932,7 @@ Bug Fixes to C++ Support
932932
- Fix a bug where private access specifier of overloaded function not respected. (#GH107629)
933933
- Correctly handles calling an explicit object member function template overload set
934934
through its address (``(&Foo::bar<baz>)()``).
935+
- Fix a crash when forming an invalid call to an operator with an explicit object member. (#GH147121)
935936
- Correctly handle allocations in the condition of a ``if constexpr``.(#GH120197) (#GH134820)
936937
- Fixed a crash when handling invalid member using-declaration in C++20+ mode. (#GH63254)
937938
- 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)