-
Notifications
You must be signed in to change notification settings - Fork 15k
release/19.x: [Clang][Concepts] Fix the constraint equivalence checking involving parameter packs (#102131) #106043
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@zyn0217 What do you think about merging this PR to the release branch? |
@llvm/pr-subscribers-clang Author: None (llvmbot) ChangesBackport e6974da Requested by: @zyn0217 Full diff: https://github.com/llvm/llvm-project/pull/106043.diff 2 Files Affected:
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>;
+ } {}
+
+}
|
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. |
How about we deploy that in 19.0.2? It seems like the safest course of action at this point. |
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)
@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. |
Backport e6974da
Requested by: @zyn0217