llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Mital Ashok (MitalAshok) <details> <summary>Changes</summary> This allows the implicitly-generated deduction guide for the copy constructor to be recognised as an initializer-list constructor, allowing CTAD for std::initializer_list --- Full diff: https://github.com/llvm/llvm-project/pull/90210.diff 4 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+2) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+11-5) - (modified) clang/lib/Sema/SemaInit.cpp (-2) - (modified) clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp (+8-3) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 92563262cc6737..4065de5745aae6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -581,6 +581,8 @@ Bug Fixes to C++ Support - Fixed a use-after-free bug in parsing of type constraints with default arguments that involve lambdas. (#GH67235) - Fixed bug in which the body of a consteval lambda within a template was not parsed as within an immediate function context. +- Fix CTAD for ``std::initializer_list``. This allows ``std::initializer_list{1, 2, 3}`` to be deduced as + ``std::initializer_list<int>`` as intended. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index abdbc9d8830c03..8d98f593817bda 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -12052,11 +12052,17 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) { Template = Specialization->getSpecializedTemplate(); Arguments = Specialization->getTemplateArgs().data(); - } else if (const TemplateSpecializationType *TST = - Ty->getAs<TemplateSpecializationType>()) { - Template = dyn_cast_or_null<ClassTemplateDecl>( - TST->getTemplateName().getAsTemplateDecl()); - Arguments = TST->template_arguments().begin(); + } else { + const TemplateSpecializationType *TST = nullptr; + if (auto *ICN = Ty->getAs<InjectedClassNameType>()) + TST = ICN->getInjectedTST(); + else + TST = Ty->getAs<TemplateSpecializationType>(); + if (TST) { + Template = dyn_cast_or_null<ClassTemplateDecl>( + TST->getTemplateName().getAsTemplateDecl()); + Arguments = TST->template_arguments().begin(); + } } if (!Template) return false; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 003a157990d307..842d165c60d94c 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -10790,8 +10790,6 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( // FIXME: Perform "exact type" matching first, per CWG discussion? // Or implement this via an implied 'T(T) -> T' deduction guide? - // FIXME: Do we need/want a std::initializer_list<T> special case? - // Look up deduction guides, including those synthesized from constructors. // // C++1z [over.match.class.deduct]p1: diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp index 2f067ea53a5029..90404f115c75f7 100644 --- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp @@ -12,14 +12,19 @@ namespace std { size_t n; initializer_list(); }; - // FIXME: This should probably not be necessary. - template<typename T> initializer_list(initializer_list<T>) -> initializer_list<T>; } template<typename T> constexpr bool has_type(...) { return false; } template<typename T> constexpr bool has_type(T&) { return true; } -std::initializer_list il = {1, 2, 3, 4, 5}; +std::initializer_list il1 = {1, 2, 3, 4, 5}; +auto il2 = std::initializer_list{1, 2, 3, 4}; +auto il3 = std::initializer_list{il1}; +auto il4 = std::initializer_list{il1, il1, il1}; +static_assert(has_type<std::initializer_list<int>>(il1)); +static_assert(has_type<std::initializer_list<int>>(il2)); +static_assert(has_type<std::initializer_list<int>>(il3)); +static_assert(has_type<std::initializer_list<std::initializer_list<int>>>(il4)); template<typename T> struct vector { template<typename Iter> vector(Iter, Iter); `````````` </details> https://github.com/llvm/llvm-project/pull/90210 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits