[clang] [Clang][SemaCXX] Fix bug where unexpanded lambda captures where assumed to have size 1 (PR #101385)
Mital Ashok via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 31 11:44:51 PDT 2024
https://github.com/MitalAshok created https://github.com/llvm/llvm-project/pull/101385
Fixes #63677
>From 555373715bc2eb025d6580129cead087f7f45ed1 Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Fri, 7 Jul 2023 14:31:03 +0100
Subject: [PATCH] [Clang][SemaCXX] Fix bug where unexpanded lambda captures
where assumed to have size 1
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Sema/SemaTemplateInstantiate.cpp | 3 ++-
clang/lib/Sema/TreeTransform.h | 6 ++---
clang/test/SemaCXX/lambda-pack-expansion.cpp | 27 ++++++++++++++++++++
4 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3c2e0282d1c72..2f4158ac36ac2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -170,6 +170,7 @@ Bug Fixes to C++ Support
- Fixed a failed assertion when checking invalid delete operator declaration. (#GH96191)
- Fix a crash when checking destructor reference with an invalid initializer. (#GH97230)
- Clang now correctly parses potentially declarative nested-name-specifiers in pointer-to-member declarators.
+- Fix init-capture packs having a size of one before being instantiated. (#GH63677)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 8995d461362d7..de470739ab78e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1447,7 +1447,8 @@ namespace {
}
void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) {
- if (Old->isParameterPack()) {
+ if (Old->isParameterPack() &&
+ (NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) {
SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old);
for (auto *New : NewDecls)
SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 8d3e1edf7a45d..540e1e0cb8df0 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -14340,14 +14340,14 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
RetainExpansion, NumExpansions))
return ExprError();
+ assert(!RetainExpansion && "Should not need to retain expansion after a "
+ "capture since it cannot be extended");
if (Expand) {
for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
SubstInitCapture(SourceLocation(), std::nullopt);
}
- }
- if (!Expand || RetainExpansion) {
- ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+ } else {
SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
}
diff --git a/clang/test/SemaCXX/lambda-pack-expansion.cpp b/clang/test/SemaCXX/lambda-pack-expansion.cpp
index 221d1d01a06ae..77b2e244753a9 100644
--- a/clang/test/SemaCXX/lambda-pack-expansion.cpp
+++ b/clang/test/SemaCXX/lambda-pack-expansion.cpp
@@ -41,3 +41,30 @@ int h(Ts... ts) {
}
}
+
+namespace GH63677 {
+
+template<typename>
+void f() {
+ []<typename... Ts>() -> void {
+ [...us = Ts{}]{
+ (Ts(us), ...);
+ };
+ }.template operator()<int, int>();
+}
+
+template void f<int>();
+
+template <class>
+inline constexpr auto fun =
+ []<class... Ts>(Ts... ts) {
+ return [... us = (Ts&&) ts]<class Fun>(Fun&& fn) mutable {
+ return static_cast<Fun&&>(fn)(static_cast<Ts&&>(us)...);
+ };
+ };
+
+void f() {
+ [[maybe_unused]] auto s = fun<int>(1, 2, 3, 4);
+}
+
+}
More information about the cfe-commits
mailing list