Skip to content

Commit 258462c

Browse files
author
hobois
committed
Choose the correct deduction guide
If there are two guides, one of them generated from a non-templated constructor and the other from a templated constructor, then the standard gives priority to the first. Clang detected ambiguity before, now the correct guide is chosen. As an unrelated minor change, fix the issue #64020, which could've led to incorrect behavior if further development inserted code after a call to isAddressSpaceSubsetOf() which specified the two parameters in the wrong order.
1 parent 69b7e25 commit 258462c

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

clang/lib/Sema/SemaOverload.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -10153,6 +10153,21 @@ bool clang::isBetterOverloadCandidate(
1015310153
// -- F1 is the copy deduction candidate(16.3.1.8) and F2 is not
1015410154
if (Guide1->getDeductionCandidateKind() == DeductionCandidate::Copy)
1015510155
return true;
10156+
if (Guide2->getDeductionCandidateKind() == DeductionCandidate::Copy)
10157+
return false;
10158+
10159+
// --F1 is generated from a non-template constructor and F2 is generated
10160+
// from a constructor template
10161+
const auto *Constructor1 = Guide1->getCorrespondingConstructor();
10162+
const auto *Constructor2 = Guide2->getCorrespondingConstructor();
10163+
if (Constructor1 && Constructor2) {
10164+
bool isC1Templated = Constructor1->getTemplatedKind() !=
10165+
FunctionDecl::TemplatedKind::TK_NonTemplate;
10166+
bool isC2Templated = Constructor2->getTemplatedKind() !=
10167+
FunctionDecl::TemplatedKind::TK_NonTemplate;
10168+
if (isC1Templated != isC2Templated)
10169+
return isC2Templated;
10170+
}
1015610171
}
1015710172
}
1015810173

@@ -10196,7 +10211,7 @@ bool clang::isBetterOverloadCandidate(
1019610211
if (AS1 != AS2) {
1019710212
if (Qualifiers::isAddressSpaceSupersetOf(AS2, AS1))
1019810213
return true;
10199-
if (Qualifiers::isAddressSpaceSupersetOf(AS2, AS1))
10214+
if (Qualifiers::isAddressSpaceSupersetOf(AS1, AS2))
1020010215
return false;
1020110216
}
1020210217
}

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2129,7 +2129,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
21292129
Function = CXXDeductionGuideDecl::Create(
21302130
SemaRef.Context, DC, D->getInnerLocStart(),
21312131
InstantiatedExplicitSpecifier, NameInfo, T, TInfo,
2132-
D->getSourceRange().getEnd(), /*Ctor=*/nullptr,
2132+
D->getSourceRange().getEnd(), DGuide->getCorrespondingConstructor(),
21332133
DGuide->getDeductionCandidateKind());
21342134
Function->setAccess(D->getAccess());
21352135
} else {

clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,13 @@ int main() {
8585

8686

8787
}
88+
89+
namespace deduceTemplatedConstructor{
90+
template <class T> struct A {
91+
A(T, T, int);
92+
template<class U>
93+
A(int, T, U);
94+
};
95+
96+
A x(1, 2, 3); // no-error
97+
}

0 commit comments

Comments
 (0)