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 <zyn7...@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 <zyn7...@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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits