Skip to content

Commit da1a201

Browse files
committed
address Erich's, format, add release notes
1 parent 0330d3b commit da1a201

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ C++ Language Changes
9696
asm((std::string_view("nop")) ::: (std::string_view("memory")));
9797
}
9898

99+
- Clang now implements the changes to overload resolution proposed by `P3606 <https://wg21.link/P3606R0>`_.
100+
If a non-template candidate exists in an overload set that is a perfect match (all conversion sequences
101+
are identity conversions) template candiates are not instantiated.
102+
Diagnostics that would have resulted from the instantiation of these template candidates are no longer
103+
produced. This aligns Clang closer to the behavior of GCC and fixes (#GH62096), (#GH74581), and (#GH74581).
104+
99105
C++2c Feature Support
100106
^^^^^^^^^^^^^^^^^^^^^
101107

clang/include/clang/Sema/Overload.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,17 @@ class Sema;
408408
}
409409

410410
bool isPerfect(const ASTContext &C) const {
411-
if(!isIdentityConversion())
411+
if (!isIdentityConversion())
412412
return false;
413-
if(!ReferenceBinding)
413+
// If we are not performing a reference binding, we can skip comparing
414+
// the types, which has a noticeable performance impact.
415+
if (!ReferenceBinding) {
416+
assert(C.hasSameType(getFromType(), getToType(2)));
414417
return true;
415-
if(!C.hasSameType(getFromType(), getToType(2)))
418+
}
419+
if (!C.hasSameType(getFromType(), getToType(2)))
416420
return false;
417-
if(BindsToRvalue && IsLvalueReference)
421+
if (BindsToRvalue && IsLvalueReference)
418422
return false;
419423
return true;
420424
}
@@ -755,6 +759,9 @@ class Sema;
755759
Standard.setAllToTypes(T);
756760
}
757761

762+
/// A conversion sequence is perfect if
763+
/// it is an identity conversion and
764+
/// the type of the source is the same as the type of the target.
758765
bool isPerfect(const ASTContext &C) const {
759766
return isStandard() && Standard.isPerfect(C);
760767
}
@@ -995,6 +1002,8 @@ class Sema;
9951002
return false;
9961003
}
9971004

1005+
// An overload is a perfect match if the conversion
1006+
// sequences for each argument are perfect.
9981007
bool isPerfectMatch(const ASTContext &Ctx) const {
9991008
if (!Viable)
10001009
return false;
@@ -1046,7 +1055,10 @@ class Sema;
10461055
};
10471056

10481057
struct DeferredTemplateOverloadCandidate {
1058+
1059+
// intrusive linked list support for allocateDeferredCandidate
10491060
DeferredTemplateOverloadCandidate *Next = nullptr;
1061+
10501062
enum Kind { Function, Method, Conversion };
10511063

10521064
LLVM_PREFERRED_TYPE(Kind)
@@ -1256,6 +1268,11 @@ class Sema;
12561268
return reinterpret_cast<T *>(FreeSpaceStart);
12571269
}
12581270

1271+
// Because the size of OverloadCandidateSet has a noticeable impact on
1272+
// performance, we store each deferred template candidate in the slab
1273+
// allocator such that deferred candidates are ultimately a singly-linked
1274+
// intrusive linked list. This ends up being much more efficient than a
1275+
// SmallVector that is empty in the common case.
12591276
template <typename T> T *allocateDeferredCandidate() {
12601277
T *C = slabAllocate<T>(1);
12611278
if (!FirstDeferredCandidate)

0 commit comments

Comments
 (0)