[clang] [Clang] Fix deduction of explicit object member functions (PR #140030)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 15 02:25:27 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: cor3ntin (cor3ntin)
<details>
<summary>Changes</summary>
When taking the address of an overload set containing an explicit object member, we should not take the
explicit object parameter into account.
---
Full diff: https://github.com/llvm/llvm-project/pull/140030.diff
5 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1)
- (modified) clang/include/clang/Sema/Sema.h (+1)
- (modified) clang/lib/Sema/SemaOverload.cpp (+4)
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+10-1)
- (modified) clang/test/SemaCXX/cxx2b-deducing-this.cpp (+27)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 31c517338c21f..1f17bc6e5c8e3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -710,6 +710,7 @@ Bug Fixes to C++ Support
- Clang now correctly parses arbitrary order of ``[[]]``, ``__attribute__`` and ``alignas`` attributes for declarations (#GH133107)
- Fixed a crash when forming an invalid function type in a dependent context. (#GH138657) (#GH115725) (#GH68852)
- Clang no longer segfaults when there is a configuration mismatch between modules and their users (http://crbug.com/400353616).
+- Fix an incorrect deduction when calling an explicit object member function template through an overload set address.
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6ea7ee281e14d..5ec67087aeea4 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12576,6 +12576,7 @@ class Sema final : public SemaBase {
bool PartialOverloading, bool AggregateDeductionCandidate,
bool PartialOrdering, QualType ObjectType,
Expr::Classification ObjectClassification,
+ bool ForOverloadSetAddressResolution,
llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent);
/// Deduce template arguments when taking the address of a function
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index e20a41c10ccaa..23304e12f8c31 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7846,6 +7846,8 @@ static void AddMethodTemplateCandidateImmediately(
MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info,
PartialOverloading, /*AggregateDeductionCandidate=*/false,
/*PartialOrdering=*/false, ObjectType, ObjectClassification,
+ CandidateSet.getKind() ==
+ clang::OverloadCandidateSet::CSK_AddressOfOverloadSet,
[&](ArrayRef<QualType> ParamTypes) {
return S.CheckNonDependentConversions(
MethodTmpl, ParamTypes, Args, CandidateSet, Conversions,
@@ -7960,6 +7962,8 @@ static void AddTemplateOverloadCandidateImmediately(
/*PartialOrdering=*/false,
/*ObjectType=*/QualType(),
/*ObjectClassification=*/Expr::Classification(),
+ CandidateSet.getKind() ==
+ OverloadCandidateSet::CSK_AddressOfOverloadSet,
[&](ArrayRef<QualType> ParamTypes) {
return S.CheckNonDependentConversions(
FunctionTemplate, ParamTypes, Args, CandidateSet, Conversions,
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 5dc06ebc2a235..217d57d67f067 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4432,6 +4432,7 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
bool PartialOverloading, bool AggregateDeductionCandidate,
bool PartialOrdering, QualType ObjectType,
Expr::Classification ObjectClassification,
+ bool ForOverloadSetAddressResolution,
llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent) {
if (FunctionTemplate->isInvalidDecl())
return TemplateDeductionResult::Invalid;
@@ -4440,7 +4441,15 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
unsigned NumParams = Function->getNumParams();
bool HasExplicitObject = false;
int ExplicitObjectOffset = 0;
- if (Function->hasCXXExplicitFunctionObjectParameter()) {
+
+ // [C++26] [over.call.func]p3
+ // If the primary-expression is the address of an overload set,
+ // the argument list is the same as the expression-list in the call.
+ // Otherwise, the argument list is the expression-list in the call augmented
+ // by the addition of an implied object argument as in a qualified function
+ // call.
+ if (!ForOverloadSetAddressResolution &&
+ Function->hasCXXExplicitFunctionObjectParameter()) {
HasExplicitObject = true;
ExplicitObjectOffset = 1;
}
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
index 7e392213710a4..2286da8d1c0e5 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
@@ -926,6 +926,33 @@ struct C {
(&fref)();
}
};
+
+struct CTpl {
+ template <typename T>
+ constexpr int c(this const CTpl&, T) { // #P2797-ctpl-1
+ return 42;
+ }
+
+ template <typename T>
+ void c(T)&; // #P2797-ctpl-2
+
+ template <typename T>
+ static void c(T = 0, T = 0); // #P2797-ctpl-3
+
+ void d() {
+ c(0); // expected-error {{call to member function 'c' is ambiguous}}
+ // expected-note@#P2797-ctpl-1{{candidate}}
+ // expected-note@#P2797-ctpl-2{{candidate}}
+ // expected-note@#P2797-ctpl-3{{candidate}}
+ (CTpl::c)(0); // expected-error {{call to member function 'c' is ambiguous}}
+ // expected-note@#P2797-ctpl-1{{candidate}}
+ // expected-note@#P2797-ctpl-2{{candidate}}
+ // expected-note@#P2797-ctpl-3{{candidate}}
+
+ static_assert((&CTpl::c)(CTpl{}, 0) == 42); // selects #1
+ }
+};
+
}
namespace GH85992 {
``````````
</details>
https://github.com/llvm/llvm-project/pull/140030
More information about the cfe-commits
mailing list