@@ -1177,7 +1177,7 @@ getTrivialTypeTemplateArgument(Sema &S, SourceLocation Loc, QualType T) {
1177
1177
namespace { enum class IsTupleLike { TupleLike, NotTupleLike, Error }; }
1178
1178
1179
1179
static IsTupleLike isTupleLike(Sema &S, SourceLocation Loc, QualType T,
1180
- llvm::APSInt &Size ) {
1180
+ unsigned &OutSize ) {
1181
1181
EnterExpressionEvaluationContext ContextRAII(
1182
1182
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
1183
1183
@@ -1218,10 +1218,24 @@ static IsTupleLike isTupleLike(Sema &S, SourceLocation Loc, QualType T,
1218
1218
if (E.isInvalid())
1219
1219
return IsTupleLike::Error;
1220
1220
1221
+ llvm::APSInt Size;
1221
1222
E = S.VerifyIntegerConstantExpression(E.get(), &Size, Diagnoser);
1222
1223
if (E.isInvalid())
1223
1224
return IsTupleLike::Error;
1224
1225
1226
+ // The implementation limit is UINT_MAX-1, to allow this to be passed down on
1227
+ // an UnsignedOrNone.
1228
+ if (Size < 0 || Size >= UINT_MAX) {
1229
+ llvm::SmallVector<char, 16> Str;
1230
+ Size.toString(Str);
1231
+ S.Diag(Loc, diag::err_decomp_decl_std_tuple_size_invalid)
1232
+ << printTemplateArgs(S.Context.getPrintingPolicy(), Args,
1233
+ /*Params=*/nullptr)
1234
+ << StringRef(Str.data(), Str.size());
1235
+ return IsTupleLike::Error;
1236
+ }
1237
+
1238
+ OutSize = Size.getExtValue();
1225
1239
return IsTupleLike::TupleLike;
1226
1240
}
1227
1241
@@ -1279,9 +1293,8 @@ struct InitializingBinding {
1279
1293
static bool checkTupleLikeDecomposition(Sema &S,
1280
1294
ArrayRef<BindingDecl *> Bindings,
1281
1295
VarDecl *Src, QualType DecompType,
1282
- const llvm::APSInt &TupleSize ) {
1296
+ unsigned NumElems ) {
1283
1297
auto *DD = cast<DecompositionDecl>(Src);
1284
- unsigned NumElems = (unsigned)TupleSize.getLimitedValue(UINT_MAX);
1285
1298
if (CheckBindingsCount(S, DD, DecompType, Bindings, NumElems))
1286
1299
return true;
1287
1300
@@ -1641,7 +1654,7 @@ void Sema::CheckCompleteDecompositionDeclaration(DecompositionDecl *DD) {
1641
1654
// C++1z [dcl.decomp]/3:
1642
1655
// if the expression std::tuple_size<E>::value is a well-formed integral
1643
1656
// constant expression, [...]
1644
- llvm::APSInt TupleSize(32) ;
1657
+ unsigned TupleSize;
1645
1658
switch (isTupleLike(*this, DD->getLocation(), DecompType, TupleSize)) {
1646
1659
case IsTupleLike::Error:
1647
1660
DD->setInvalidDecl();
@@ -1690,12 +1703,12 @@ UnsignedOrNone Sema::GetDecompositionElementCount(QualType T,
1690
1703
if (T->getAs<ComplexType>())
1691
1704
return 2u;
1692
1705
1693
- llvm::APSInt TupleSize(Ctx.getTypeSize(Ctx.getSizeType())) ;
1706
+ unsigned TupleSize;
1694
1707
switch (isTupleLike(*this, Loc, T, TupleSize)) {
1695
1708
case IsTupleLike::Error:
1696
1709
return std::nullopt;
1697
1710
case IsTupleLike::TupleLike:
1698
- return static_cast<unsigned>( TupleSize.getExtValue()) ;
1711
+ return TupleSize;
1699
1712
case IsTupleLike::NotTupleLike:
1700
1713
break;
1701
1714
}
0 commit comments