Skip to content

Commit 40e9947

Browse files
author
Yuanfang Chen
committed
[Clang] follow-up D128745, remove ClangABICompat checks
Per discussions in D128745, remove ClangABICompat checks for implementations of DR692/DR1395/DR1432. This is a potentially breaking changes, so the release note is updated accordingly. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D136120
1 parent 48732d3 commit 40e9947

File tree

4 files changed

+85
-142
lines changed

4 files changed

+85
-142
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,21 @@ code bases.
161161
- The ``-fexperimental-new-pass-manager`` and ``-fno-legacy-pass-manager``
162162
flags have been removed. These have been no-ops since 15.0.0.
163163

164+
- As a side effect of implementing DR692/DR1395/DR1432, Clang now rejects some
165+
overloaded function templates as ambiguous when one of the candidates has a
166+
trailing parameter pack.
167+
168+
.. code-block:: c++
169+
170+
template <typename T> void g(T, T = T());
171+
template <typename T, typename... U> void g(T, U...);
172+
void h() {
173+
// This is rejected due to ambiguity between the pack and the
174+
// default argument. Only parameters with arguments are considered during
175+
// partial ordering of function templates.
176+
g(42);
177+
}
178+
164179
What's New in Clang |release|?
165180
==============================
166181
Some of the major new features and improvements to Clang are listed
@@ -551,10 +566,10 @@ C2x Feature Support
551566
552567
C++ Language Changes in Clang
553568
-----------------------------
554-
- Implemented DR692, DR1395 and DR1432. Use the ``-fclang-abi-compat=15`` option
555-
to get the old partial ordering behavior regarding packs. Note that the fix for
556-
DR1432 is speculative that there is no wording or even resolution for this issue.
557-
A speculative fix for DR1432 is needed because it fixes regressions caused by DR692.
569+
- Implemented `DR692 <https://wg21.link/cwg692>`_, `DR1395 <https://wg21.link/cwg1395>`_,
570+
and `DR1432 <https://wg21.link/cwg1432>`_. The fix for DR1432 is speculative since the
571+
issue is still open and has no proposed resolution at this time. A speculative fix
572+
for DR1432 is needed to prevent regressions that would otherwise occur due to DR692.
558573
- Clang's default C++/ObjC++ standard is now ``gnu++17`` instead of ``gnu++14``.
559574
This means Clang will by default accept code using features from C++17 and
560575
conforming GNU extensions. Projects incompatible with C++17 can add

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 66 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,9 +1128,7 @@ DeduceTemplateArguments(Sema &S,
11281128
// During partial ordering, if Ai was originally a function parameter pack:
11291129
// - if P does not contain a function parameter type corresponding to Ai then
11301130
// Ai is ignored;
1131-
bool ClangABICompat15 = S.Context.getLangOpts().getClangABICompat() <=
1132-
LangOptions::ClangABI::Ver15;
1133-
if (!ClangABICompat15 && PartialOrdering && ArgIdx + 1 == NumArgs &&
1131+
if (PartialOrdering && ArgIdx + 1 == NumArgs &&
11341132
isa<PackExpansionType>(Args[ArgIdx]))
11351133
return Sema::TDK_Success;
11361134

@@ -2466,9 +2464,6 @@ static bool isSameTemplateArg(ASTContext &Context,
24662464
if (X.getKind() != Y.getKind())
24672465
return false;
24682466

2469-
bool ClangABICompat15 =
2470-
Context.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver15;
2471-
24722467
switch (X.getKind()) {
24732468
case TemplateArgument::Null:
24742469
llvm_unreachable("Comparing NULL template argument");
@@ -2500,45 +2495,33 @@ static bool isSameTemplateArg(ASTContext &Context,
25002495
return XID == YID;
25012496
}
25022497

2503-
case TemplateArgument::Pack:
2504-
if (ClangABICompat15) {
2505-
if (X.pack_size() != Y.pack_size())
2498+
case TemplateArgument::Pack: {
2499+
unsigned PackIterationSize = X.pack_size();
2500+
if (X.pack_size() != Y.pack_size()) {
2501+
if (!PartialOrdering)
25062502
return false;
25072503

2508-
for (TemplateArgument::pack_iterator XP = X.pack_begin(),
2509-
XPEnd = X.pack_end(),
2510-
YP = Y.pack_begin();
2511-
XP != XPEnd; ++XP, ++YP)
2512-
if (!isSameTemplateArg(Context, *XP, *YP, PartialOrdering,
2513-
PackExpansionMatchesPack))
2514-
return false;
2515-
} else {
2516-
unsigned PackIterationSize = X.pack_size();
2517-
if (X.pack_size() != Y.pack_size()) {
2518-
if (!PartialOrdering)
2519-
return false;
2520-
2521-
// C++0x [temp.deduct.type]p9:
2522-
// During partial ordering, if Ai was originally a pack expansion:
2523-
// - if P does not contain a template argument corresponding to Ai
2524-
// then Ai is ignored;
2525-
bool XHasMoreArg = X.pack_size() > Y.pack_size();
2526-
if (!(XHasMoreArg && X.pack_elements().back().isPackExpansion()) &&
2527-
!(!XHasMoreArg && Y.pack_elements().back().isPackExpansion()))
2528-
return false;
2529-
2530-
if (XHasMoreArg)
2531-
PackIterationSize = Y.pack_size();
2532-
}
2504+
// C++0x [temp.deduct.type]p9:
2505+
// During partial ordering, if Ai was originally a pack expansion:
2506+
// - if P does not contain a template argument corresponding to Ai
2507+
// then Ai is ignored;
2508+
bool XHasMoreArg = X.pack_size() > Y.pack_size();
2509+
if (!(XHasMoreArg && X.pack_elements().back().isPackExpansion()) &&
2510+
!(!XHasMoreArg && Y.pack_elements().back().isPackExpansion()))
2511+
return false;
25332512

2534-
ArrayRef<TemplateArgument> XP = X.pack_elements();
2535-
ArrayRef<TemplateArgument> YP = Y.pack_elements();
2536-
for (unsigned i = 0; i < PackIterationSize; ++i)
2537-
if (!isSameTemplateArg(Context, XP[i], YP[i], PartialOrdering,
2538-
PackExpansionMatchesPack))
2539-
return false;
2513+
if (XHasMoreArg)
2514+
PackIterationSize = Y.pack_size();
25402515
}
2516+
2517+
ArrayRef<TemplateArgument> XP = X.pack_elements();
2518+
ArrayRef<TemplateArgument> YP = Y.pack_elements();
2519+
for (unsigned i = 0; i < PackIterationSize; ++i)
2520+
if (!isSameTemplateArg(Context, XP[i], YP[i], PartialOrdering,
2521+
PackExpansionMatchesPack))
2522+
return false;
25412523
return true;
2524+
}
25422525
}
25432526

25442527
llvm_unreachable("Invalid TemplateArgument Kind!");
@@ -5245,34 +5228,30 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
52455228

52465229
// This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
52475230
// there is no wording or even resolution for this issue.
5248-
bool ClangABICompat15 =
5249-
Context.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver15;
5250-
if (!ClangABICompat15) {
5251-
for (int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
5252-
QualType T1 = FD1->getParamDecl(i)->getType().getCanonicalType();
5253-
QualType T2 = FD2->getParamDecl(i)->getType().getCanonicalType();
5254-
auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
5255-
auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
5256-
if (!TST1 || !TST2)
5257-
continue;
5258-
const TemplateArgument &TA1 = TST1->template_arguments().back();
5259-
if (TA1.getKind() == TemplateArgument::Pack) {
5260-
assert(TST1->template_arguments().size() ==
5261-
TST2->template_arguments().size());
5262-
const TemplateArgument &TA2 = TST2->template_arguments().back();
5263-
assert(TA2.getKind() == TemplateArgument::Pack);
5264-
unsigned PackSize1 = TA1.pack_size();
5265-
unsigned PackSize2 = TA2.pack_size();
5266-
bool IsPackExpansion1 =
5267-
PackSize1 && TA1.pack_elements().back().isPackExpansion();
5268-
bool IsPackExpansion2 =
5269-
PackSize2 && TA2.pack_elements().back().isPackExpansion();
5270-
if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
5271-
if (PackSize1 > PackSize2 && IsPackExpansion1)
5272-
return FT2;
5273-
if (PackSize1 < PackSize2 && IsPackExpansion2)
5274-
return FT1;
5275-
}
5231+
for (int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
5232+
QualType T1 = FD1->getParamDecl(i)->getType().getCanonicalType();
5233+
QualType T2 = FD2->getParamDecl(i)->getType().getCanonicalType();
5234+
auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
5235+
auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
5236+
if (!TST1 || !TST2)
5237+
continue;
5238+
const TemplateArgument &TA1 = TST1->template_arguments().back();
5239+
if (TA1.getKind() == TemplateArgument::Pack) {
5240+
assert(TST1->template_arguments().size() ==
5241+
TST2->template_arguments().size());
5242+
const TemplateArgument &TA2 = TST2->template_arguments().back();
5243+
assert(TA2.getKind() == TemplateArgument::Pack);
5244+
unsigned PackSize1 = TA1.pack_size();
5245+
unsigned PackSize2 = TA2.pack_size();
5246+
bool IsPackExpansion1 =
5247+
PackSize1 && TA1.pack_elements().back().isPackExpansion();
5248+
bool IsPackExpansion2 =
5249+
PackSize2 && TA2.pack_elements().back().isPackExpansion();
5250+
if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
5251+
if (PackSize1 > PackSize2 && IsPackExpansion1)
5252+
return FT2;
5253+
if (PackSize1 < PackSize2 && IsPackExpansion2)
5254+
return FT1;
52765255
}
52775256
}
52785257
}
@@ -5618,29 +5597,25 @@ getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1,
56185597

56195598
// This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
56205599
// there is no wording or even resolution for this issue.
5621-
bool ClangABICompat15 = S.Context.getLangOpts().getClangABICompat() <=
5622-
LangOptions::ClangABI::Ver15;
5623-
if (!ClangABICompat15) {
5624-
auto *TST1 = cast<TemplateSpecializationType>(T1);
5625-
auto *TST2 = cast<TemplateSpecializationType>(T2);
5626-
const TemplateArgument &TA1 = TST1->template_arguments().back();
5627-
if (TA1.getKind() == TemplateArgument::Pack) {
5628-
assert(TST1->template_arguments().size() ==
5629-
TST2->template_arguments().size());
5630-
const TemplateArgument &TA2 = TST2->template_arguments().back();
5631-
assert(TA2.getKind() == TemplateArgument::Pack);
5632-
unsigned PackSize1 = TA1.pack_size();
5633-
unsigned PackSize2 = TA2.pack_size();
5634-
bool IsPackExpansion1 =
5635-
PackSize1 && TA1.pack_elements().back().isPackExpansion();
5636-
bool IsPackExpansion2 =
5637-
PackSize2 && TA2.pack_elements().back().isPackExpansion();
5638-
if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
5639-
if (PackSize1 > PackSize2 && IsPackExpansion1)
5640-
return GetP2()(P1, P2);
5641-
if (PackSize1 < PackSize2 && IsPackExpansion2)
5642-
return P1;
5643-
}
5600+
auto *TST1 = cast<TemplateSpecializationType>(T1);
5601+
auto *TST2 = cast<TemplateSpecializationType>(T2);
5602+
const TemplateArgument &TA1 = TST1->template_arguments().back();
5603+
if (TA1.getKind() == TemplateArgument::Pack) {
5604+
assert(TST1->template_arguments().size() ==
5605+
TST2->template_arguments().size());
5606+
const TemplateArgument &TA2 = TST2->template_arguments().back();
5607+
assert(TA2.getKind() == TemplateArgument::Pack);
5608+
unsigned PackSize1 = TA1.pack_size();
5609+
unsigned PackSize2 = TA2.pack_size();
5610+
bool IsPackExpansion1 =
5611+
PackSize1 && TA1.pack_elements().back().isPackExpansion();
5612+
bool IsPackExpansion2 =
5613+
PackSize2 && TA2.pack_elements().back().isPackExpansion();
5614+
if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
5615+
if (PackSize1 > PackSize2 && IsPackExpansion1)
5616+
return GetP2()(P1, P2);
5617+
if (PackSize1 < PackSize2 && IsPackExpansion2)
5618+
return P1;
56445619
}
56455620
}
56465621

clang/test/CodeGen/partial-order-variadic.cpp

Lines changed: 0 additions & 33 deletions
This file was deleted.

clang/test/SemaCXX/pre-dr692.cpp

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)