@@ -1177,7 +1177,7 @@ getTrivialTypeTemplateArgument(Sema &S, SourceLocation Loc, QualType T) {
11771177namespace { enum class IsTupleLike { TupleLike, NotTupleLike, Error }; }
11781178
11791179static IsTupleLike isTupleLike(Sema &S, SourceLocation Loc, QualType T,
1180- llvm::APSInt &Size ) {
1180+ unsigned &OutSize ) {
11811181 EnterExpressionEvaluationContext ContextRAII(
11821182 S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
11831183
@@ -1218,10 +1218,24 @@ static IsTupleLike isTupleLike(Sema &S, SourceLocation Loc, QualType T,
12181218 if (E.isInvalid())
12191219 return IsTupleLike::Error;
12201220
1221+ llvm::APSInt Size;
12211222 E = S.VerifyIntegerConstantExpression(E.get(), &Size, Diagnoser);
12221223 if (E.isInvalid())
12231224 return IsTupleLike::Error;
12241225
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();
12251239 return IsTupleLike::TupleLike;
12261240}
12271241
@@ -1279,9 +1293,8 @@ struct InitializingBinding {
12791293static bool checkTupleLikeDecomposition(Sema &S,
12801294 ArrayRef<BindingDecl *> Bindings,
12811295 VarDecl *Src, QualType DecompType,
1282- const llvm::APSInt &TupleSize ) {
1296+ unsigned NumElems ) {
12831297 auto *DD = cast<DecompositionDecl>(Src);
1284- unsigned NumElems = (unsigned)TupleSize.getLimitedValue(UINT_MAX);
12851298 if (CheckBindingsCount(S, DD, DecompType, Bindings, NumElems))
12861299 return true;
12871300
@@ -1641,7 +1654,7 @@ void Sema::CheckCompleteDecompositionDeclaration(DecompositionDecl *DD) {
16411654 // C++1z [dcl.decomp]/3:
16421655 // if the expression std::tuple_size<E>::value is a well-formed integral
16431656 // constant expression, [...]
1644- llvm::APSInt TupleSize(32) ;
1657+ unsigned TupleSize;
16451658 switch (isTupleLike(*this, DD->getLocation(), DecompType, TupleSize)) {
16461659 case IsTupleLike::Error:
16471660 DD->setInvalidDecl();
@@ -1690,12 +1703,12 @@ UnsignedOrNone Sema::GetDecompositionElementCount(QualType T,
16901703 if (T->getAs<ComplexType>())
16911704 return 2u;
16921705
1693- llvm::APSInt TupleSize(Ctx.getTypeSize(Ctx.getSizeType())) ;
1706+ unsigned TupleSize;
16941707 switch (isTupleLike(*this, Loc, T, TupleSize)) {
16951708 case IsTupleLike::Error:
16961709 return std::nullopt;
16971710 case IsTupleLike::TupleLike:
1698- return static_cast<unsigned>( TupleSize.getExtValue()) ;
1711+ return TupleSize;
16991712 case IsTupleLike::NotTupleLike:
17001713 break;
17011714 }
0 commit comments