https://github.com/cor3ntin created https://github.com/llvm/llvm-project/pull/147996
When an overload is invalid, we try to initialize each conversion sequence for the purpose of recovery, but we failed to initialize explicit objects, leading to a crash Fixes #147121 >From 6d3df177b7061cb71bfb2943dabc1c211e2043ff Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Thu, 10 Jul 2025 18:05:42 +0200 Subject: [PATCH] [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 --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaOverload.cpp | 6 +-- clang/test/SemaCXX/cxx2b-deducing-this.cpp | 57 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ca00a80d10eca..3f1587d8113db 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 7af3acacb5ba6..1b54628c5e564 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -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 && @@ -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()) { diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index 3a3dc8855d827..6987d0c020457 100644 --- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp +++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp @@ -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}} +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits