[clang] 40e9947 - [Clang] follow-up D128745, remove ClangABICompat checks
Yuanfang Chen via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 2 16:33:34 PDT 2022
Author: Yuanfang Chen
Date: 2022-11-02T16:33:10-07:00
New Revision: 40e99473170f5045e0b5f2cafabd2a1be8c7ec26
URL: https://github.com/llvm/llvm-project/commit/40e99473170f5045e0b5f2cafabd2a1be8c7ec26
DIFF: https://github.com/llvm/llvm-project/commit/40e99473170f5045e0b5f2cafabd2a1be8c7ec26.diff
LOG: [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
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplateDeduction.cpp
Removed:
clang/test/CodeGen/partial-order-variadic.cpp
clang/test/SemaCXX/pre-dr692.cpp
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1198926974bff..435d9ded7c72e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -161,6 +161,21 @@ code bases.
- The ``-fexperimental-new-pass-manager`` and ``-fno-legacy-pass-manager``
flags have been removed. These have been no-ops since 15.0.0.
+- As a side effect of implementing DR692/DR1395/DR1432, Clang now rejects some
+ overloaded function templates as ambiguous when one of the candidates has a
+ trailing parameter pack.
+
+ .. code-block:: c++
+
+ template <typename T> void g(T, T = T());
+ template <typename T, typename... U> void g(T, U...);
+ void h() {
+ // This is rejected due to ambiguity between the pack and the
+ // default argument. Only parameters with arguments are considered during
+ // partial ordering of function templates.
+ g(42);
+ }
+
What's New in Clang |release|?
==============================
Some of the major new features and improvements to Clang are listed
@@ -551,10 +566,10 @@ C2x Feature Support
C++ Language Changes in Clang
-----------------------------
-- Implemented DR692, DR1395 and DR1432. Use the ``-fclang-abi-compat=15`` option
- to get the old partial ordering behavior regarding packs. Note that the fix for
- DR1432 is speculative that there is no wording or even resolution for this issue.
- A speculative fix for DR1432 is needed because it fixes regressions caused by DR692.
+- Implemented `DR692 <https://wg21.link/cwg692>`_, `DR1395 <https://wg21.link/cwg1395>`_,
+ and `DR1432 <https://wg21.link/cwg1432>`_. The fix for DR1432 is speculative since the
+ issue is still open and has no proposed resolution at this time. A speculative fix
+ for DR1432 is needed to prevent regressions that would otherwise occur due to DR692.
- Clang's default C++/ObjC++ standard is now ``gnu++17`` instead of ``gnu++14``.
This means Clang will by default accept code using features from C++17 and
conforming GNU extensions. Projects incompatible with C++17 can add
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 17c0e2f04f4bd..3db06a51e4eb7 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -1128,9 +1128,7 @@ DeduceTemplateArguments(Sema &S,
// During partial ordering, if Ai was originally a function parameter pack:
// - if P does not contain a function parameter type corresponding to Ai then
// Ai is ignored;
- bool ClangABICompat15 = S.Context.getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver15;
- if (!ClangABICompat15 && PartialOrdering && ArgIdx + 1 == NumArgs &&
+ if (PartialOrdering && ArgIdx + 1 == NumArgs &&
isa<PackExpansionType>(Args[ArgIdx]))
return Sema::TDK_Success;
@@ -2466,9 +2464,6 @@ static bool isSameTemplateArg(ASTContext &Context,
if (X.getKind() != Y.getKind())
return false;
- bool ClangABICompat15 =
- Context.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver15;
-
switch (X.getKind()) {
case TemplateArgument::Null:
llvm_unreachable("Comparing NULL template argument");
@@ -2500,45 +2495,33 @@ static bool isSameTemplateArg(ASTContext &Context,
return XID == YID;
}
- case TemplateArgument::Pack:
- if (ClangABICompat15) {
- if (X.pack_size() != Y.pack_size())
+ case TemplateArgument::Pack: {
+ unsigned PackIterationSize = X.pack_size();
+ if (X.pack_size() != Y.pack_size()) {
+ if (!PartialOrdering)
return false;
- for (TemplateArgument::pack_iterator XP = X.pack_begin(),
- XPEnd = X.pack_end(),
- YP = Y.pack_begin();
- XP != XPEnd; ++XP, ++YP)
- if (!isSameTemplateArg(Context, *XP, *YP, PartialOrdering,
- PackExpansionMatchesPack))
- return false;
- } else {
- unsigned PackIterationSize = X.pack_size();
- if (X.pack_size() != Y.pack_size()) {
- if (!PartialOrdering)
- return false;
-
- // C++0x [temp.deduct.type]p9:
- // During partial ordering, if Ai was originally a pack expansion:
- // - if P does not contain a template argument corresponding to Ai
- // then Ai is ignored;
- bool XHasMoreArg = X.pack_size() > Y.pack_size();
- if (!(XHasMoreArg && X.pack_elements().back().isPackExpansion()) &&
- !(!XHasMoreArg && Y.pack_elements().back().isPackExpansion()))
- return false;
-
- if (XHasMoreArg)
- PackIterationSize = Y.pack_size();
- }
+ // C++0x [temp.deduct.type]p9:
+ // During partial ordering, if Ai was originally a pack expansion:
+ // - if P does not contain a template argument corresponding to Ai
+ // then Ai is ignored;
+ bool XHasMoreArg = X.pack_size() > Y.pack_size();
+ if (!(XHasMoreArg && X.pack_elements().back().isPackExpansion()) &&
+ !(!XHasMoreArg && Y.pack_elements().back().isPackExpansion()))
+ return false;
- ArrayRef<TemplateArgument> XP = X.pack_elements();
- ArrayRef<TemplateArgument> YP = Y.pack_elements();
- for (unsigned i = 0; i < PackIterationSize; ++i)
- if (!isSameTemplateArg(Context, XP[i], YP[i], PartialOrdering,
- PackExpansionMatchesPack))
- return false;
+ if (XHasMoreArg)
+ PackIterationSize = Y.pack_size();
}
+
+ ArrayRef<TemplateArgument> XP = X.pack_elements();
+ ArrayRef<TemplateArgument> YP = Y.pack_elements();
+ for (unsigned i = 0; i < PackIterationSize; ++i)
+ if (!isSameTemplateArg(Context, XP[i], YP[i], PartialOrdering,
+ PackExpansionMatchesPack))
+ return false;
return true;
+ }
}
llvm_unreachable("Invalid TemplateArgument Kind!");
@@ -5245,34 +5228,30 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
// This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
// there is no wording or even resolution for this issue.
- bool ClangABICompat15 =
- Context.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver15;
- if (!ClangABICompat15) {
- for (int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
- QualType T1 = FD1->getParamDecl(i)->getType().getCanonicalType();
- QualType T2 = FD2->getParamDecl(i)->getType().getCanonicalType();
- auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
- auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
- if (!TST1 || !TST2)
- continue;
- const TemplateArgument &TA1 = TST1->template_arguments().back();
- if (TA1.getKind() == TemplateArgument::Pack) {
- assert(TST1->template_arguments().size() ==
- TST2->template_arguments().size());
- const TemplateArgument &TA2 = TST2->template_arguments().back();
- assert(TA2.getKind() == TemplateArgument::Pack);
- unsigned PackSize1 = TA1.pack_size();
- unsigned PackSize2 = TA2.pack_size();
- bool IsPackExpansion1 =
- PackSize1 && TA1.pack_elements().back().isPackExpansion();
- bool IsPackExpansion2 =
- PackSize2 && TA2.pack_elements().back().isPackExpansion();
- if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
- if (PackSize1 > PackSize2 && IsPackExpansion1)
- return FT2;
- if (PackSize1 < PackSize2 && IsPackExpansion2)
- return FT1;
- }
+ for (int i = 0, e = std::min(NumParams1, NumParams2); i < e; ++i) {
+ QualType T1 = FD1->getParamDecl(i)->getType().getCanonicalType();
+ QualType T2 = FD2->getParamDecl(i)->getType().getCanonicalType();
+ auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
+ auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
+ if (!TST1 || !TST2)
+ continue;
+ const TemplateArgument &TA1 = TST1->template_arguments().back();
+ if (TA1.getKind() == TemplateArgument::Pack) {
+ assert(TST1->template_arguments().size() ==
+ TST2->template_arguments().size());
+ const TemplateArgument &TA2 = TST2->template_arguments().back();
+ assert(TA2.getKind() == TemplateArgument::Pack);
+ unsigned PackSize1 = TA1.pack_size();
+ unsigned PackSize2 = TA2.pack_size();
+ bool IsPackExpansion1 =
+ PackSize1 && TA1.pack_elements().back().isPackExpansion();
+ bool IsPackExpansion2 =
+ PackSize2 && TA2.pack_elements().back().isPackExpansion();
+ if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
+ if (PackSize1 > PackSize2 && IsPackExpansion1)
+ return FT2;
+ if (PackSize1 < PackSize2 && IsPackExpansion2)
+ return FT1;
}
}
}
@@ -5618,29 +5597,25 @@ getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1,
// This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
// there is no wording or even resolution for this issue.
- bool ClangABICompat15 = S.Context.getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver15;
- if (!ClangABICompat15) {
- auto *TST1 = cast<TemplateSpecializationType>(T1);
- auto *TST2 = cast<TemplateSpecializationType>(T2);
- const TemplateArgument &TA1 = TST1->template_arguments().back();
- if (TA1.getKind() == TemplateArgument::Pack) {
- assert(TST1->template_arguments().size() ==
- TST2->template_arguments().size());
- const TemplateArgument &TA2 = TST2->template_arguments().back();
- assert(TA2.getKind() == TemplateArgument::Pack);
- unsigned PackSize1 = TA1.pack_size();
- unsigned PackSize2 = TA2.pack_size();
- bool IsPackExpansion1 =
- PackSize1 && TA1.pack_elements().back().isPackExpansion();
- bool IsPackExpansion2 =
- PackSize2 && TA2.pack_elements().back().isPackExpansion();
- if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
- if (PackSize1 > PackSize2 && IsPackExpansion1)
- return GetP2()(P1, P2);
- if (PackSize1 < PackSize2 && IsPackExpansion2)
- return P1;
- }
+ auto *TST1 = cast<TemplateSpecializationType>(T1);
+ auto *TST2 = cast<TemplateSpecializationType>(T2);
+ const TemplateArgument &TA1 = TST1->template_arguments().back();
+ if (TA1.getKind() == TemplateArgument::Pack) {
+ assert(TST1->template_arguments().size() ==
+ TST2->template_arguments().size());
+ const TemplateArgument &TA2 = TST2->template_arguments().back();
+ assert(TA2.getKind() == TemplateArgument::Pack);
+ unsigned PackSize1 = TA1.pack_size();
+ unsigned PackSize2 = TA2.pack_size();
+ bool IsPackExpansion1 =
+ PackSize1 && TA1.pack_elements().back().isPackExpansion();
+ bool IsPackExpansion2 =
+ PackSize2 && TA2.pack_elements().back().isPackExpansion();
+ if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
+ if (PackSize1 > PackSize2 && IsPackExpansion1)
+ return GetP2()(P1, P2);
+ if (PackSize1 < PackSize2 && IsPackExpansion2)
+ return P1;
}
}
diff --git a/clang/test/CodeGen/partial-order-variadic.cpp b/clang/test/CodeGen/partial-order-variadic.cpp
deleted file mode 100644
index a10cd6812f988..0000000000000
--- a/clang/test/CodeGen/partial-order-variadic.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fclang-abi-compat=15 -DCLANG_ABI_COMPAT=15 %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,AFTER-15
-
-// CHECK: %struct.S = type { i8 }
-// CHECK: @_Z2ggiRi
-// CHECK: @_Z1gIiJEERiPT_DpT0_
-template <typename T, typename... U> int &g(T *, U...);
-template <typename T> void g(T);
-template <typename T, typename... Ts> struct S;
-template <typename T> struct S<T> {};
-void gg(int i, int &r) {
- r = g(&i);
- S<int> a;
-}
-
-// CHECK: @_Z1hIJiEEvDpPT_
-template<class ...T> void h(T*...) {}
-template<class T> void h(const T&) {}
-template void h(int*);
-
-#if !defined(CLANG_ABI_COMPAT)
-
-// AFTER-15: @_Z1fIiJEEvPT_DpT0_
-template<class T, class... U> void f(T*, U...){}
-template<class T> void f(T){}
-template void f(int*);
-
-template<class T, class... U> struct A;
-template<class T1, class T2, class... U> struct A<T1,T2*,U...> {};
-template<class T1, class T2> struct A<T1,T2>;
-template struct A<int, int*>;
-
-#endif
diff --git a/clang/test/SemaCXX/pre-dr692.cpp b/clang/test/SemaCXX/pre-dr692.cpp
deleted file mode 100644
index 87eac318dc067..0000000000000
--- a/clang/test/SemaCXX/pre-dr692.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: %clang_cc1 %s -std=c++11 -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -fclang-abi-compat=15
-
-template <typename... T> struct A1 {};
-template <typename U, typename... T> struct A2 {};
-template <class T1, class... U> void e1(A1<T1, U...>); // expected-note {{candidate}}
-template <class T1> void e1(A1<T1>); // expected-note {{candidate}}
-template <class T1, class... U> void e2(A2<T1, U...>); // expected-note {{candidate}}
-template <class T1> void e2(A2<T1>); // expected-note {{candidate}}
-void h() {
- A1<int> b1;
- e1(b1); // expected-error{{call to 'e1' is ambiguous}}
- A2<int> b2;
- e2(b2); // expected-error{{call to 'e2' is ambiguous}}
-}
More information about the cfe-commits
mailing list