Author: Matheus Izvekov Date: 2022-10-31T17:57:17+01:00 New Revision: edf1a2e89340c8fa64a679e7d4ec2b5ee92ec40f
URL: https://github.com/llvm/llvm-project/commit/edf1a2e89340c8fa64a679e7d4ec2b5ee92ec40f DIFF: https://github.com/llvm/llvm-project/commit/edf1a2e89340c8fa64a679e7d4ec2b5ee92ec40f.diff LOG: [clang] Fix handling of unexpanded packs in template argument expressions. Closes #58679. Signed-off-by: Matheus Izvekov <mizve...@gmail.com> Differential Revision: https://reviews.llvm.org/D136977 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 95910fd9f4269..f751f96d29e9d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -266,6 +266,8 @@ Bug Fixes `Issue 45736 <https://github.com/llvm/llvm-project/issues/45736>`_ - Fix an issue when performing constraints partial ordering on non-template functions. `Issue 56154 <https://github.com/llvm/llvm-project/issues/56154>`_ +- Fix handling of unexpanded packs in template argument expressions. + `Issue 58679 <https://github.com/llvm/llvm-project/issues/58679>`_ Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 23b4e3f60cef1..917c6c162e6d0 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6818,7 +6818,8 @@ class Sema final { Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue); } ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, - bool DiscardedValue, bool IsConstexpr = false); + bool DiscardedValue, bool IsConstexpr = false, + bool IsTemplateArgument = false); StmtResult ActOnFinishFullStmt(Stmt *Stmt); // Marks SS invalid if it represents an incomplete type. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index bb9cfe30e5d4d..41c4348de0791 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -8713,14 +8713,14 @@ Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl, } ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, - bool DiscardedValue, - bool IsConstexpr) { + bool DiscardedValue, bool IsConstexpr, + bool IsTemplateArgument) { ExprResult FullExpr = FE; if (!FullExpr.get()) return ExprError(); - if (DiagnoseUnexpandedParameterPack(FullExpr.get())) + if (!IsTemplateArgument && DiagnoseUnexpandedParameterPack(FullExpr.get())) return ExprError(); if (DiscardedValue) { diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 45bca3a31d3a7..a65cdbed7fd02 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -5862,9 +5862,9 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, // C++2a [intro.execution]p5: // A full-expression is [...] a constant-expression [...] - Result = - S.ActOnFinishFullExpr(Result.get(), From->getExprLoc(), - /*DiscardedValue=*/false, /*IsConstexpr=*/true); + Result = S.ActOnFinishFullExpr(Result.get(), From->getExprLoc(), + /*DiscardedValue=*/false, /*IsConstexpr=*/true, + CCE == Sema::CCEKind::CCEK_TemplateArg); if (Result.isInvalid()) return Result; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index bf6acd52f2856..985ac271e9d13 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -7156,11 +7156,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, } // If either the parameter has a dependent type or the argument is - // type-dependent, there's nothing we can check now. The argument only - // contains an unexpanded pack during partial ordering, and there's - // nothing more we can check in that case. - if (ParamType->isDependentType() || Arg->isTypeDependent() || - Arg->containsUnexpandedParameterPack()) { + // type-dependent, there's nothing we can check now. + if (ParamType->isDependentType() || Arg->isTypeDependent()) { // Force the argument to the type of the parameter to maintain invariants. auto *PE = dyn_cast<PackExpansionExpr>(Arg); if (PE) diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index fb8d931710cad..2d82a4f26b147 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -502,3 +502,22 @@ template <class> using B = char; template <class ...Cs> int C{ A<B<Cs>>{}... }; // expected-error {{implicit instantiation of undefined template}} #endif } // namespace GH56094 + +namespace GH58679 { +#if __cplusplus >= 201402L +template <class> constexpr int A = 1; + +template <int> struct B; +template <> struct B<1> { using b1 = void; }; + +template <class> using C = char; + +template <class... Ds> int D{ B<A<C<Ds>>>{}... }; + +struct E { + template <class E1, class = typename B<A<E1>>::b1> E(E1); +}; + +template <typename... Es> int F{ E(C<Es>{})... }; +#endif +} // namespace GH58679 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits