[clang] edf1a2e - [clang] Fix handling of unexpanded packs in template argument expressions.
Matheus Izvekov via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 31 09:58:26 PDT 2022
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 <mizvekov at 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
More information about the cfe-commits
mailing list