[clang] 8dcc7ee - [clang][AST] Widen TypeTraitExprBitfields.NumArgs to 16 bits.

Bruno Ricci via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 9 07:40:06 PDT 2020


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


        


More information about the cfe-commits mailing list