[clang] [clang][Sema] Avoid non-empty unexpanded pack assertion for FunctionParmPackExpr (PR #69224)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 23 06:54:01 PDT 2023
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/69224
>From ec6425590890e050dc212a7e13ca27c866a4fb22 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Mon, 16 Oct 2023 22:50:08 +0800
Subject: [PATCH 1/2] [clang][Sema] Avoid non-empty unexpanded pack assertion
for FunctionParmPackExpr
Closes https://github.com/llvm/llvm-project/issues/61460.
We have FunctionParmPackExpr that serves as the unexpanded
expression but from which the visitor collects none, which may
lead to assertion failure during the template instantiation.
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Sema/SemaTemplateVariadic.cpp | 26 +++++++++++++++++++------
clang/test/SemaCXX/pr61460.cpp | 13 +++++++++++++
3 files changed, 35 insertions(+), 6 deletions(-)
create mode 100644 clang/test/SemaCXX/pr61460.cpp
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c292e012c4548d9..ea7a29b098a80ed 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -476,6 +476,8 @@ Bug Fixes in This Version
Fixes (`#65143 <https://github.com/llvm/llvm-project/issues/65143>`_)
- Fix crash in formatting the real/imaginary part of a complex lvalue.
Fixes (`#69218 <https://github.com/llvm/llvm-project/issues/69218>`_)
+- Fixed an issue that a benign assertion might hit when instantiating a pack expansion
+ inside a lambda. (`#61460 <https://github.com/llvm/llvm-project/issues/61460>`_)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index dfcc78dafdc4c31..521d34dc18d0166 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -388,8 +388,8 @@ bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
return false;
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
- T->getTypeLoc());
+ CollectUnexpandedParameterPacksVisitor(Unexpanded)
+ .TraverseTypeLoc(T->getTypeLoc());
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
}
@@ -402,6 +402,20 @@ bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
if (!E->containsUnexpandedParameterPack())
return false;
+ // Exception: The `CollectUnexpandedParameterPacksVisitor` collects nothing
+ // from a FunctionParmPackExpr. In the context where the collector is being
+ // used such as `collectUnexpandedParameterPacks`, this type of expression
+ // is not expected to be collected.
+ //
+ // Nonetheless, this function for diagnosis is still called anyway during
+ // template instantiation, with an expression of such a type if we're inside a
+ // lambda with unexpanded parameters.
+ //
+ // Rule out this case to prevent the assertion failure.
+ if (auto *Expr = dyn_cast<FunctionParmPackExpr>(E);
+ Expr && getEnclosingLambda())
+ return false;
+
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
@@ -442,7 +456,7 @@ bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
CollectUnexpandedParameterPacksVisitor(Unexpanded)
- .TraverseNestedNameSpecifier(SS.getScopeRep());
+ .TraverseNestedNameSpecifier(SS.getScopeRep());
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
UPPC, Unexpanded);
@@ -479,7 +493,7 @@ bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
CollectUnexpandedParameterPacksVisitor(Unexpanded)
- .TraverseType(NameInfo.getName().getCXXNameType());
+ .TraverseType(NameInfo.getName().getCXXNameType());
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
}
@@ -493,7 +507,7 @@ bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
CollectUnexpandedParameterPacksVisitor(Unexpanded)
- .TraverseTemplateName(Template);
+ .TraverseTemplateName(Template);
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
}
@@ -506,7 +520,7 @@ bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
CollectUnexpandedParameterPacksVisitor(Unexpanded)
- .TraverseTemplateArgumentLoc(Arg);
+ .TraverseTemplateArgumentLoc(Arg);
assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
}
diff --git a/clang/test/SemaCXX/pr61460.cpp b/clang/test/SemaCXX/pr61460.cpp
new file mode 100644
index 000000000000000..471b1b39d23c2b7
--- /dev/null
+++ b/clang/test/SemaCXX/pr61460.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++17 %s -fsyntax-only -verify
+
+template <typename... Ts> void g(Ts... p1s) {
+ (void)[&](auto... p2s) { ([&] { p1s; p2s; }, ...); };
+}
+
+void f1() {
+ g();
+}
+
+template <typename... Ts> void g2(Ts... p1s) {
+ (void)[&](auto... p2s) { [&] { p1s; p2s; }; }; // expected-error {{expression contains unexpanded parameter pack 'p2s'}}
+}
>From 697d1163c0d10ef2934ca8b268aadb069ae6857d Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Mon, 23 Oct 2023 21:50:55 +0800
Subject: [PATCH 2/2] Use llvm::isa
---
clang/lib/Sema/SemaTemplateVariadic.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 521d34dc18d0166..ca0b1f81e6b5038 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -412,8 +412,7 @@ bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
// lambda with unexpanded parameters.
//
// Rule out this case to prevent the assertion failure.
- if (auto *Expr = dyn_cast<FunctionParmPackExpr>(E);
- Expr && getEnclosingLambda())
+ if (isa<FunctionParmPackExpr>(E) && getEnclosingLambda())
return false;
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
More information about the cfe-commits
mailing list