[clang] [Clang][Concepts] Fix the constraint equivalence checking involving parameter packs (PR #102131)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 23 21:04:00 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

<details>
<summary>Changes</summary>

We established an instantiation scope in order for constraint equivalence checking to properly map the uninstantiated parameters. 

That mechanism mapped even packs to themselves. Consequently, parameter packs e.g. appearing in a function call, were not expanded. So they would end up becoming `SubstTemplateTypeParmPackType`s that circularly depend on the canonical declaration of the function template, which is not yet determined, hence the spurious error.

No release note as I plan to backport it to 19.

Fixes https://github.com/llvm/llvm-project/issues/101735

---
Full diff: https://github.com/llvm/llvm-project/pull/102131.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaConcept.cpp (+9-2) 
- (modified) clang/test/SemaTemplate/concepts-out-of-line-def.cpp (+23) 


``````````diff
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index d4c9d044985e34..14a67f35a8f9f8 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -972,8 +972,15 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
   // equivalence.
   LocalInstantiationScope ScopeForParameters(S);
   if (auto *FD = DeclInfo.getDecl()->getAsFunction())
-    for (auto *PVD : FD->parameters())
-      ScopeForParameters.InstantiatedLocal(PVD, PVD);
+    for (auto *PVD : FD->parameters()) {
+      if (!PVD->isParameterPack()) {
+        ScopeForParameters.InstantiatedLocal(PVD, PVD);
+        continue;
+      }
+      // Parameter packs should expand to a size-of-1 argument.
+      ScopeForParameters.MakeInstantiatedLocalArgPack(PVD);
+      ScopeForParameters.InstantiatedLocalPackArg(PVD, PVD);
+    }
 
   std::optional<Sema::CXXThisScopeRAII> ThisScope;
 
diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index 0142efcdc3ee86..333187b0d74ad6 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -599,3 +599,26 @@ template <class DerT>
 unsigned long DerivedCollection<DerTs...>::index() {}
 
 } // namespace GH72557
+
+namespace GH101735 {
+
+template <class, class>
+concept True = true;
+
+template <typename T>
+class A {
+  template <typename... Ts>
+  void method(Ts&... ts)
+    requires requires (T t) {
+      { t.method(static_cast<Ts &&>(ts)...) } -> True<void>;
+    };
+};
+
+template <typename T>
+template <typename... Ts>
+void A<T>::method(Ts&... ts)
+  requires requires (T t) {
+    { t.method(static_cast<Ts &&>(ts)...) } -> True<void>;
+  } {}
+
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/102131


More information about the cfe-commits mailing list