diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d4db877a823ea52..c4fa017b982bbd5 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -382,6 +382,9 @@ Bug Fixes to C++ Support - Fix a crash when using ``source_location`` in the trailing return type of a lambda expression. (#GH67134) - A follow-up fix was added for (#GH61460), as the previous fix was not entirely correct. (#GH86361) - Fixed a crash in the typo correction of an invalid CTAD guide. (#GH107887) +- Fixed a crash when clang tries to subtitute parameter pack while retaining the parameter + pack. #GH63819, #GH107560 + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 4bbc024587915c3..ff745b3385fcd91 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -113,9 +113,13 @@ class TreeTransform { class ForgetPartiallySubstitutedPackRAII { Derived &Self; TemplateArgument Old; + // Set the pack expansion index to -1 to avoid pack substitution and + // indicate that parameter packs should be instantiated as themselves. + Sema::ArgumentPackSubstitutionIndexRAII ResetPackSubstIndex; public: - ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) { + ForgetPartiallySubstitutedPackRAII(Derived &Self) + : Self(Self), ResetPackSubstIndex(Self.getSema(), -1) { Old = Self.ForgetPartiallySubstitutedPack(); } diff --git a/clang/test/SemaTemplate/pack-deduction.cpp b/clang/test/SemaTemplate/pack-deduction.cpp index e42709820e9cff8..28fb127a3864418 100644 --- a/clang/test/SemaTemplate/pack-deduction.cpp +++ b/clang/test/SemaTemplate/pack-deduction.cpp @@ -185,3 +185,17 @@ void Run() { Outer::Inner<0>().Test(1,1); } } + +namespace GH107560 { +int bar(...); + +template struct Int {}; + +template +constexpr auto foo(T... x) -> decltype(bar(T(x)...)) { return 10; } + +template +constexpr auto baz(Int(T())>... x) -> int { return 1; } + +static_assert(baz, Int<2>, Int<3>>(Int<10>(), Int<10>(), Int<10>()) == 1, ""); +}