[clang] [Clang] Fix a crash when diagnosing wrong conversion to explicit object parameter (PR #147996)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 10 09:33:59 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Corentin Jabot (cor3ntin)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/147996.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1)
- (modified) clang/lib/Sema/SemaOverload.cpp (+3-3)
- (modified) clang/test/SemaCXX/cxx2b-deducing-this.cpp (+57)
``````````diff
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 at -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 at -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 at -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 at -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 at -1{{cannot increment value of type 'S3'}}
+ s3[];
+ // expected-error at -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 at -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}}
+}
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/147996
More information about the cfe-commits
mailing list