Skip to content

Conversation

llvmbot
Copy link
Member

@llvmbot llvmbot commented Aug 26, 2024

Backport e6974da

Requested by: @zyn0217

@llvmbot llvmbot added this to the LLVM 19.X Release milestone Aug 26, 2024
@llvmbot
Copy link
Member Author

llvmbot commented Aug 26, 2024

@zyn0217 What do you think about merging this PR to the release branch?

@llvmbot llvmbot requested a review from zyn0217 August 26, 2024 06:51
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Aug 26, 2024
@llvmbot
Copy link
Member Author

llvmbot commented Aug 26, 2024

@llvm/pr-subscribers-clang

Author: None (llvmbot)

Changes

Backport e6974da

Requested by: @zyn0217


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

2 Files Affected:

  • (modified) clang/lib/Sema/SemaConcept.cpp (+24-2)
  • (modified) clang/test/SemaTemplate/concepts-out-of-line-def.cpp (+23)
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index c34d32002b5ad7..244f6ef2f53faa 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -969,8 +969,30 @@ 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;
+      }
+      // This is hacky: we're mapping the parameter pack to a size-of-1 argument
+      // to avoid building SubstTemplateTypeParmPackTypes for
+      // PackExpansionTypes. The SubstTemplateTypeParmPackType node would
+      // otherwise reference the AssociatedDecl of the template arguments, which
+      // is, in this case, the template declaration.
+      //
+      // However, as we are in the process of comparing potential
+      // re-declarations, the canonical declaration is the declaration itself at
+      // this point. So if we didn't expand these packs, we would end up with an
+      // incorrect profile difference because we will be profiling the
+      // canonical types!
+      //
+      // FIXME: Improve the "no-transform" machinery in FindInstantiatedDecl so
+      // that we can eliminate the Scope in the cases where the declarations are
+      // not necessarily instantiated. It would also benefit the noexcept
+      // specifier comparison.
+      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>;
+  } {}
+
+}

@tru
Copy link
Collaborator

tru commented Aug 26, 2024

Is this a major fix or regression fix?

@zyn0217
Copy link
Contributor

zyn0217 commented Aug 26, 2024

Is this a major fix or regression fix?

It is a follow-up fix for the previous bug fix incorporated in 19. 04d20b1

But this isn't a regression since clang wasn't working properly in such cases, nor a major fix as I don't think it would affect much but rather ensure more correctness.

We have a report from @yuxuanchen1997 that some production codes rely on this to compile, so I think it merits a backport.

@zyn0217 zyn0217 requested review from cor3ntin and mizvekov and removed request for zyn0217 August 26, 2024 08:07
@tru
Copy link
Collaborator

tru commented Sep 13, 2024

Can this be reviewed @cor3ntin @mizvekov

@cor3ntin
Copy link
Contributor

How about we deploy that in 19.0.2? It seems like the safest course of action at this point.

@tru
Copy link
Collaborator

tru commented Sep 16, 2024

Can someone approve this and I'll merge it after final.

…arameter packs (llvm#102131)

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 llvm#101735

---------

Co-authored-by: cor3ntin <[email protected]>
(cherry picked from commit e6974da)
@tru tru merged commit 3e512ba into llvm:release/19.x Sep 24, 2024
7 of 10 checks passed
Copy link

@zyn0217 (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
Development

Successfully merging this pull request may close these issues.

5 participants