[clang-tools-extra] [clang] [llvm] [concepts] Extract function template pack arguments from the current instantiation if possible (PR #80594)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 4 03:38:15 PST 2024


https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/80594

>From c04bb951d35e0f767ea9b0fed8e200b161d646e1 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sun, 4 Feb 2024 17:35:16 +0800
Subject: [PATCH 1/3] [concepts] Fixes for gh72557

---
 clang/docs/ReleaseNotes.rst                    |  3 +++
 clang/lib/Sema/SemaTemplateInstantiate.cpp     | 15 +++++++++++++--
 .../SemaTemplate/concepts-out-of-line-def.cpp  | 18 ++++++++++++++++++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e634db3c718c9..c4afe545c4b85 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -197,6 +197,9 @@ Bug Fixes to C++ Support
   Fixes (`#67976 <https://github.com/llvm/llvm-project/issues/67976>`_)
 - Fix crash and diagnostic with const qualified member operator new.
   Fixes (`#79748 <https://github.com/llvm/llvm-project/issues/79748>`_)
+- Fixed a crash where substituting into a requires-expression that involves parameter packs
+  during the equivalence determination of two constraint expressions.
+  (`#72557 <https://github.com/llvm/llvm-project/issues/72557>`_)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 01b78e4424fb5..220883ea9395f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -241,10 +241,21 @@ Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
 
     while (const Type *Ty = NNS ? NNS->getAsType() : nullptr) {
       if (NNS->isInstantiationDependent()) {
-        if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>())
+        if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
+          ArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
+          if (TSTy->isCurrentInstantiation()) {
+            auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();
+            if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
+              Arguments = CTD->getInjectedTemplateArgs();
+            else if (auto *Specializtion =
+                         dyn_cast<ClassTemplateSpecializationDecl>(RD))
+              Arguments =
+                  Specializtion->getTemplateInstantiationArgs().asArray();
+          }
           Result.addOuterTemplateArguments(
-              const_cast<FunctionTemplateDecl *>(FTD), TSTy->template_arguments(),
+              const_cast<FunctionTemplateDecl *>(FTD), Arguments,
               /*Final=*/false);
+        }
       }
 
       NNS = NNS->getPrefix();
diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index b6fea2e0b4b31..0142efcdc3ee8 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -581,3 +581,21 @@ void S<T>::test(T target, U... value)
   }
 {}
 } // namespace GH74447
+
+namespace GH72557 {
+
+template <typename...>
+concept IsAnyOf = true;
+
+template <class... DerTs> struct DerivedCollection {
+  template <class DerT>
+    requires IsAnyOf<DerTs...>
+  unsigned long index();
+};
+
+template <class... DerTs>
+template <class DerT>
+  requires IsAnyOf<DerTs...>
+unsigned long DerivedCollection<DerTs...>::index() {}
+
+} // namespace GH72557

>From 70962f401c17151bbe4e9d95b651d1ad5d30206f Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sun, 4 Feb 2024 19:20:19 +0800
Subject: [PATCH 2/3] Add comments

---
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 220883ea9395f..8faa8c5b5257e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -243,6 +243,23 @@ Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
       if (NNS->isInstantiationDependent()) {
         if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
           ArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
+          // Prefer template arguments from the injected-class-type if possible.
+          // For example,
+          // ```cpp
+          // template <class... Pack> struct S {
+          //   template <class T> void foo();
+          // };
+          // template <class... Pack> template <class T>
+          //           ^^^^^^^^^^^^^ InjectedTemplateArgs
+          //           They're of kind TemplateArgument::Pack, not of
+          //           TemplateArgument::Type.
+          // void S<Pack...>::foo() {}
+          //        ^^^^^^^
+          //        TSTy->template_arguments() (which are of PackExpansionType)
+          // ```
+          // This meets the contract in
+          // TreeTransform::TryExpandParameterPacks that the template arguments
+          // for unexpanded parameters should be of a Pack kind.
           if (TSTy->isCurrentInstantiation()) {
             auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();
             if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())

>From cf520b632ca54cd70ca5fb6274b5d0e32a8765f3 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sun, 4 Feb 2024 19:37:52 +0800
Subject: [PATCH 3/3] Fix typo

---
 clang/lib/Sema/SemaTemplateInstantiate.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 878b557a999e1..6d59180bc446d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -264,10 +264,10 @@ Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
             auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();
             if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
               Arguments = CTD->getInjectedTemplateArgs();
-            else if (auto *Specializtion =
+            else if (auto *Specialization =
                          dyn_cast<ClassTemplateSpecializationDecl>(RD))
               Arguments =
-                  Specializtion->getTemplateInstantiationArgs().asArray();
+                  Specialization->getTemplateInstantiationArgs().asArray();
           }
           Result.addOuterTemplateArguments(
               const_cast<FunctionTemplateDecl *>(FTD), Arguments,



More information about the cfe-commits mailing list