[clang] 7536ebf - [Clang][SemaCXX] Fix bug where unexpanded lambda captures where assumed to have size 1 (#101385)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 5 01:16:58 PDT 2024
Author: Mital Ashok
Date: 2024-08-05T16:16:55+08:00
New Revision: 7536ebf0ea8e2d09f47ee77e0d60470b5eeb2743
URL: https://github.com/llvm/llvm-project/commit/7536ebf0ea8e2d09f47ee77e0d60470b5eeb2743
DIFF: https://github.com/llvm/llvm-project/commit/7536ebf0ea8e2d09f47ee77e0d60470b5eeb2743.diff
LOG: [Clang][SemaCXX] Fix bug where unexpanded lambda captures where assumed to have size 1 (#101385)
Fixes #63677
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/lib/Sema/TreeTransform.h
clang/test/SemaCXX/lambda-pack-expansion.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 17696ee9ca484..6f50ab07f1fc0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -185,6 +185,7 @@ Bug Fixes to C++ Support
- Clang now correctly recognizes the correct context for parameter
substitutions in concepts, so it doesn't incorrectly complain of missing
module imports in those situations. (#GH60336)
+- 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