From 8dcc7eecb75b39d723fd6fee566369bf67e43fdf Mon Sep 17 00:00:00 2001 From: Bruno Ricci Date: Tue, 9 Jun 2020 15:10:03 +0100 Subject: [PATCH] [clang][AST] Widen TypeTraitExprBitfields.NumArgs to 16 bits. `32 - 8 - 1 - NumExprBits` is now only equal to 6, which is way too small. Add a test so that this does not happen again. --- clang/include/clang/AST/Stmt.h | 6 ++++-- clang/lib/AST/ExprCXX.cpp | 4 ++++ clang/test/SemaCXX/type-traits.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 530fb10..fdcc213 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -775,8 +775,10 @@ protected: /// the trait evaluated true or false. unsigned Value : 1; - /// The number of arguments to this type trait. - unsigned NumArgs : 32 - 8 - 1 - NumExprBits; + /// The number of arguments to this type trait. According to [implimits] + /// 8 bits would be enough, but we require (and test for) at least 16 bits + /// to mirror FunctionType. + unsigned NumArgs; }; class DependentScopeDeclRefExprBitfields { diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 3aff282..9d28555 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1580,8 +1580,12 @@ TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind, : Expr(TypeTraitExprClass, T, VK_RValue, OK_Ordinary), Loc(Loc), RParenLoc(RParenLoc) { TypeTraitExprBits.Kind = Kind; + assert(static_cast(Kind) == TypeTraitExprBits.Kind && + "TypeTraitExprBits.Kind overflow!"); TypeTraitExprBits.Value = Value; TypeTraitExprBits.NumArgs = Args.size(); + assert(Args.size() == TypeTraitExprBits.NumArgs && + "TypeTraitExprBits.NumArgs overflow!"); auto **ToArgs = getTrailingObjects(); for (unsigned I = 0, N = Args.size(); I != N; ++I) diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index 9104bfc..59ae311 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -2829,3 +2829,35 @@ namespace ConstClass { }; static_assert(!__is_trivially_assignable(B&, const B&), ""); } + +namespace type_trait_expr_numargs_overflow { + // Make sure that TypeTraitExpr can store 16 bits worth of arguments. + struct S { + template S(Ts... ts) { + static_assert(sizeof...(ts) == 32768+1, ""); + } +}; + +#define T4(X) X,X,X,X +#define T16(X) T4(X),T4(X),T4(X),T4(X) +#define T64(X) T16(X),T16(X),T16(X),T16(X) +#define T256(X) T64(X),T64(X),T64(X),T64(X) +#define T1024(X) T256(X),T256(X),T256(X),T256(X) +#define T4096(X) T1024(X),T1024(X),T1024(X),T1024(X) +#define T16384(X) T4096(X),T4096(X),T4096(X),T4096(X) +#define T32768(X) T16384(X),T16384(X) + +void test() { + static_assert(__is_constructible(S, T32768(int), float), ""); +} + +#undef T4 +#undef T16 +#undef T64 +#undef T256 +#undef T1024 +#undef T4096 +#undef T16384 +#undef T32768 + +} // namespace type_trait_expr_numargs_overflow -- 2.7.4