[Clang] Fix deduction of explicit object member functions (#140030)

When taking the address of an overload set containing an explicit object
member, we should not take the
explicit object parameter into account.
This commit is contained in:
cor3ntin
2025-05-15 15:29:56 +02:00
committed by GitHub
parent d08b176edc
commit a2f156b84a
5 changed files with 43 additions and 1 deletions

View File

@@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -12576,6 +12576,7 @@ public:
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

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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 {