Skip to content

Commit a2f156b

Browse files
authored
[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.
1 parent d08b176 commit a2f156b

File tree

5 files changed

+43
-1
lines changed

5 files changed

+43
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ Bug Fixes to C++ Support
710710
- Clang now correctly parses arbitrary order of ``[[]]``, ``__attribute__`` and ``alignas`` attributes for declarations (#GH133107)
711711
- Fixed a crash when forming an invalid function type in a dependent context. (#GH138657) (#GH115725) (#GH68852)
712712
- Clang no longer segfaults when there is a configuration mismatch between modules and their users (http://crbug.com/400353616).
713+
- Fix an incorrect deduction when calling an explicit object member function template through an overload set address.
713714

714715
Bug Fixes to AST Handling
715716
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12576,6 +12576,7 @@ class Sema final : public SemaBase {
1257612576
bool PartialOverloading, bool AggregateDeductionCandidate,
1257712577
bool PartialOrdering, QualType ObjectType,
1257812578
Expr::Classification ObjectClassification,
12579+
bool ForOverloadSetAddressResolution,
1257912580
llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent);
1258012581

1258112582
/// Deduce template arguments when taking the address of a function

clang/lib/Sema/SemaOverload.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7846,6 +7846,8 @@ static void AddMethodTemplateCandidateImmediately(
78467846
MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info,
78477847
PartialOverloading, /*AggregateDeductionCandidate=*/false,
78487848
/*PartialOrdering=*/false, ObjectType, ObjectClassification,
7849+
CandidateSet.getKind() ==
7850+
clang::OverloadCandidateSet::CSK_AddressOfOverloadSet,
78497851
[&](ArrayRef<QualType> ParamTypes) {
78507852
return S.CheckNonDependentConversions(
78517853
MethodTmpl, ParamTypes, Args, CandidateSet, Conversions,
@@ -7960,6 +7962,8 @@ static void AddTemplateOverloadCandidateImmediately(
79607962
/*PartialOrdering=*/false,
79617963
/*ObjectType=*/QualType(),
79627964
/*ObjectClassification=*/Expr::Classification(),
7965+
CandidateSet.getKind() ==
7966+
OverloadCandidateSet::CSK_AddressOfOverloadSet,
79637967
[&](ArrayRef<QualType> ParamTypes) {
79647968
return S.CheckNonDependentConversions(
79657969
FunctionTemplate, ParamTypes, Args, CandidateSet, Conversions,

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4432,6 +4432,7 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
44324432
bool PartialOverloading, bool AggregateDeductionCandidate,
44334433
bool PartialOrdering, QualType ObjectType,
44344434
Expr::Classification ObjectClassification,
4435+
bool ForOverloadSetAddressResolution,
44354436
llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent) {
44364437
if (FunctionTemplate->isInvalidDecl())
44374438
return TemplateDeductionResult::Invalid;
@@ -4440,7 +4441,15 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
44404441
unsigned NumParams = Function->getNumParams();
44414442
bool HasExplicitObject = false;
44424443
int ExplicitObjectOffset = 0;
4443-
if (Function->hasCXXExplicitFunctionObjectParameter()) {
4444+
4445+
// [C++26] [over.call.func]p3
4446+
// If the primary-expression is the address of an overload set,
4447+
// the argument list is the same as the expression-list in the call.
4448+
// Otherwise, the argument list is the expression-list in the call augmented
4449+
// by the addition of an implied object argument as in a qualified function
4450+
// call.
4451+
if (!ForOverloadSetAddressResolution &&
4452+
Function->hasCXXExplicitFunctionObjectParameter()) {
44444453
HasExplicitObject = true;
44454454
ExplicitObjectOffset = 1;
44464455
}

clang/test/SemaCXX/cxx2b-deducing-this.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,33 @@ struct C {
926926
(&fref)();
927927
}
928928
};
929+
930+
struct CTpl {
931+
template <typename T>
932+
constexpr int c(this const CTpl&, T) { // #P2797-ctpl-1
933+
return 42;
934+
}
935+
936+
template <typename T>
937+
void c(T)&; // #P2797-ctpl-2
938+
939+
template <typename T>
940+
static void c(T = 0, T = 0); // #P2797-ctpl-3
941+
942+
void d() {
943+
c(0); // expected-error {{call to member function 'c' is ambiguous}}
944+
// expected-note@#P2797-ctpl-1{{candidate}}
945+
// expected-note@#P2797-ctpl-2{{candidate}}
946+
// expected-note@#P2797-ctpl-3{{candidate}}
947+
(CTpl::c)(0); // expected-error {{call to member function 'c' is ambiguous}}
948+
// expected-note@#P2797-ctpl-1{{candidate}}
949+
// expected-note@#P2797-ctpl-2{{candidate}}
950+
// expected-note@#P2797-ctpl-3{{candidate}}
951+
952+
static_assert((&CTpl::c)(CTpl{}, 0) == 42); // selects #1
953+
}
954+
};
955+
929956
}
930957

931958
namespace GH85992 {

0 commit comments

Comments
 (0)