forked from OSchip/llvm-project
[clang] Fix handling of unexpanded packs in template argument expressions.
Closes #58679. Signed-off-by: Matheus Izvekov <mizvekov@gmail.com> Differential Revision: https://reviews.llvm.org/D136977
This commit is contained in:
parent
2492c52a05
commit
edf1a2e893
|
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -6818,7 +6818,8 @@ public:
|
|||
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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue