Author: Bruno Ricci Date: 2020-06-09T15:18:15+01:00 New Revision: 8dcc7eecb75b39d723fd6fee566369bf67e43fdf
URL: https://github.com/llvm/llvm-project/commit/8dcc7eecb75b39d723fd6fee566369bf67e43fdf DIFF: https://github.com/llvm/llvm-project/commit/8dcc7eecb75b39d723fd6fee566369bf67e43fdf.diff LOG: [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. Added: Modified: clang/include/clang/AST/Stmt.h clang/lib/AST/ExprCXX.cpp clang/test/SemaCXX/type-traits.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 530fb1029c7e..fdcc213a6aed 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -775,8 +775,10 @@ class alignas(void *) Stmt { /// 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 3aff2826a1dd..9d285550ef90 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<unsigned>(Kind) == TypeTraitExprBits.Kind && + "TypeTraitExprBits.Kind overflow!"); TypeTraitExprBits.Value = Value; TypeTraitExprBits.NumArgs = Args.size(); + assert(Args.size() == TypeTraitExprBits.NumArgs && + "TypeTraitExprBits.NumArgs overflow!"); auto **ToArgs = getTrailingObjects<TypeSourceInfo *>(); 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 9104bfcb2ea4..59ae31130528 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 <typename... Ts> 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits