ychen updated this revision to Diff 463309. ychen added a comment. - Update release notes
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133683/new/ https://reviews.llvm.org/D133683 Files: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/CXX/drs/dr6xx.cpp clang/test/SemaCXX/pre-dr692.cpp
Index: clang/test/SemaCXX/pre-dr692.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/pre-dr692.cpp @@ -0,0 +1,14 @@ +// 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}} +} Index: clang/test/CXX/drs/dr6xx.cpp =================================================================== --- clang/test/CXX/drs/dr6xx.cpp +++ clang/test/CXX/drs/dr6xx.cpp @@ -1083,13 +1083,23 @@ // Also see dr1395. namespace temp_func_order_example2 { - template <typename T, typename U> struct A {}; - template <typename T, typename U> void f(U, A<U, T> *p = 0); // expected-note {{candidate}} - template <typename U> int &f(U, A<U, U> *p = 0); // expected-note {{candidate}} + template <typename... T> struct A1 {}; // expected-error 0-1{{C++11}} + template <typename U, typename... T> struct A2 {}; // expected-error 0-1{{C++11}} + template <class T1, class... U> void e1(A1<T1, U...>) = delete; // expected-error 0-2{{C++11}} + template <class T1> void e1(A1<T1>); + template <class T1, class... U> void e2(A2<T1, U...>) = delete; // expected-error 0-2{{C++11}} + template <class T1> void e2(A2<T1>); + template <typename T, typename U> void f(U, A1<U, T> *p = 0) = delete; // expected-note {{candidate}} expected-error 0-1{{C++11}} + template <typename U> int &f(U, A1<U, U> *p = 0); // expected-note {{candidate}} template <typename T> void g(T, T = T()); // expected-note {{candidate}} template <typename T, typename... U> void g(T, U...); // expected-note {{candidate}} expected-error 0-1{{C++11}} void h() { - int &r = f<int>(42, (A<int, int> *)0); + A1<int, int> a; + int &r = f<int>(42, &a); + A1<int> b1; + e1(b1); + A2<int> b2; + e2(b2); f<int>(42); // expected-error {{ambiguous}} g(42); // expected-error {{ambiguous}} } Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5222,6 +5222,39 @@ return FT1; } + // 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->getNumArgs() == TST2->getNumArgs()); + 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; + } + } + } + } + return JudgeByConstraints(); } @@ -5457,30 +5490,29 @@ return nullptr; if (Better1 && Better2) { + // 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) { - // Consider this a fix for CWG1432. Similar to the fix for CWG1395. - auto *TST1 = T1->castAs<TemplateSpecializationType>(); - auto *TST2 = T2->castAs<TemplateSpecializationType>(); - if (TST1->getNumArgs()) { - const TemplateArgument &TA1 = TST1->template_arguments().back(); - if (TA1.getKind() == TemplateArgument::Pack) { - assert(TST1->getNumArgs() == TST2->getNumArgs()); - 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->getNumArgs() == TST2->getNumArgs()); + 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; } } } Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -315,7 +315,9 @@ 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. + 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. - 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits