<div dir="auto"><div><div class="gmail_quote"><div dir="ltr">On Tue, 31 Jul 2018, 23:06 Roman Lebedev via cfe-commits, <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: lebedevri<br>
Date: Tue Jul 31 23:06:16 2018<br>
New Revision: 338489<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=338489&view=rev" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=338489&view=rev</a><br>
Log:<br>
[AST] CastExpr: BasePathSize is not large enough.<br>
<br>
Summary:<br>
rC337815 / D49508 had to cannibalize one bit of `CastExprBitfields::BasePathSize` in order to squeeze `PartOfExplicitCast` boolean.<br>
That reduced the maximal value of `PartOfExplicitCast` from 9 bits (~512) down to 8 bits (~256).<br>
Apparently, that mattered. Too bad there weren't any tests.<br>
It caused [[ <a href="https://bugs.llvm.org/show_bug.cgi?id=38356" rel="noreferrer noreferrer" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=38356</a> | PR38356 ]].<br>
<br>
So we need to increase `PartOfExplicitCast` back at least to 9 bits, or a bit more.<br>
For obvious reasons, we can't do that in `CastExprBitfields` - that would blow up the size of every `Expr`.<br>
So we need to either just add a variable into the `CastExpr` (as done here),<br>
or use `llvm::TrailingObjects`. The latter does not seem to be straight-forward.<br>
Perhaps, that needs to be done not for the `CastExpr` itself, but for all of it's `final` children.<br>
<br>
Reviewers: rjmccall, rsmith, erichkeane<br>
<br>
Reviewed By: rjmccall<br>
<br>
Subscribers: bricci, hans, cfe-commits, waddlesplash<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D50050" rel="noreferrer noreferrer" target="_blank">https://reviews.llvm.org/D50050</a><br>
<br>
Added:<br>
    cfe/trunk/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/AST/Expr.h<br>
    cfe/trunk/include/clang/AST/ExprCXX.h<br>
    cfe/trunk/include/clang/AST/ExprObjC.h<br>
    cfe/trunk/include/clang/AST/Stmt.h<br>
    cfe/trunk/lib/AST/Expr.cpp<br>
    cfe/trunk/lib/AST/ExprCXX.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/Expr.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=338489&r1=338488&r2=338489&view=diff" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=338489&r1=338488&r2=338489&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/Expr.h (original)<br>
+++ cfe/trunk/include/clang/AST/Expr.h Tue Jul 31 23:06:16 2018<br>
@@ -2787,20 +2787,26 @@ public:<br>
 /// representation in the source code (ExplicitCastExpr's derived<br>
 /// classes).<br>
 class CastExpr : public Expr {<br>
+public:<br>
+  using BasePathSizeTy = unsigned int;<br>
+  static_assert(std::numeric_limits<BasePathSizeTy>::max() >= 16384,<br>
+                "[implimits] Direct and indirect base classes [16384].");<br>
+<br>
 private:<br>
   Stmt *Op;<br>
<br>
   bool CastConsistency() const;<br>
<br>
+  BasePathSizeTy *BasePathSize();<br>
+<br>
   const CXXBaseSpecifier * const *path_buffer() const {<br>
     return const_cast<CastExpr*>(this)->path_buffer();<br>
   }<br>
   CXXBaseSpecifier **path_buffer();<br>
<br>
-  void setBasePathSize(unsigned basePathSize) {<br>
-    CastExprBits.BasePathSize = basePathSize;<br>
-    assert(CastExprBits.BasePathSize == basePathSize &&<br>
-           "basePathSize doesn't fit in bits of CastExprBits.BasePathSize!");<br>
+  void setBasePathSize(BasePathSizeTy basePathSize) {<br>
+    assert(!path_empty() && basePathSize != 0);<br>
+    *(BasePathSize()) = basePathSize;<br>
   }<br>
<br>
 protected:<br>
@@ -2823,7 +2829,9 @@ protected:<br>
         Op(op) {<br>
     CastExprBits.Kind = kind;<br>
     CastExprBits.PartOfExplicitCast = false;<br>
-    setBasePathSize(BasePathSize);<br>
+    CastExprBits.BasePathIsEmpty = BasePathSize == 0;<br>
+    if (!path_empty())<br>
+      setBasePathSize(BasePathSize);<br>
     assert(CastConsistency());<br>
   }<br>
<br>
@@ -2831,7 +2839,9 @@ protected:<br>
   CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)<br>
     : Expr(SC, Empty) {<br>
     CastExprBits.PartOfExplicitCast = false;<br>
-    setBasePathSize(BasePathSize);<br>
+    CastExprBits.BasePathIsEmpty = BasePathSize == 0;<br>
+    if (!path_empty())<br>
+      setBasePathSize(BasePathSize);<br>
   }<br>
<br>
 public:<br>
@@ -2859,8 +2869,12 @@ public:<br>
<br>
   typedef CXXBaseSpecifier **path_iterator;<br>
   typedef const CXXBaseSpecifier * const *path_const_iterator;<br>
-  bool path_empty() const { return CastExprBits.BasePathSize == 0; }<br>
-  unsigned path_size() const { return CastExprBits.BasePathSize; }<br>
+  bool path_empty() const { return CastExprBits.BasePathIsEmpty; }<br>
+  unsigned path_size() const {<br>
+    if (path_empty())<br>
+      return 0U;<br>
+    return *(const_cast<CastExpr *>(this)->BasePathSize());<br>
+  }<br>
   path_iterator path_begin() { return path_buffer(); }<br>
   path_iterator path_end() { return path_buffer() + path_size(); }<br>
   path_const_iterator path_begin() const { return path_buffer(); }<br>
@@ -2908,7 +2922,12 @@ public:<br>
 /// @endcode<br>
 class ImplicitCastExpr final<br>
     : public CastExpr,<br>
-      private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> {<br>
+      private llvm::TrailingObjects<ImplicitCastExpr, CastExpr::BasePathSizeTy,<br>
+                                    CXXBaseSpecifier *> {<br>
+  size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {<br>
+    return path_empty() ? 0 : 1;<br>
+  }<br>
+<br>
 private:<br>
   ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,<br>
                    unsigned BasePathLength, ExprValueKind VK)<br>
@@ -3013,7 +3032,8 @@ public:<br>
 /// (Type)expr. For example: @c (int)f.<br>
 class CStyleCastExpr final<br>
     : public ExplicitCastExpr,<br>
-      private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> {<br>
+      private llvm::TrailingObjects<CStyleCastExpr, CastExpr::BasePathSizeTy,<br>
+                                    CXXBaseSpecifier *> {<br>
   SourceLocation LPLoc; // the location of the left paren<br>
   SourceLocation RPLoc; // the location of the right paren<br>
<br>
@@ -3027,6 +3047,10 @@ class CStyleCastExpr final<br>
   explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)<br>
     : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }<br>
<br>
+  size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {<br>
+    return path_empty() ? 0 : 1;<br>
+  }<br>
+<br>
 public:<br>
   static CStyleCastExpr *Create(const ASTContext &Context, QualType T,<br>
                                 ExprValueKind VK, CastKind K,<br>
<br>
Modified: cfe/trunk/include/clang/AST/ExprCXX.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=338489&r1=338488&r2=338489&view=diff" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=338489&r1=338488&r2=338489&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)<br>
+++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Jul 31 23:06:16 2018<br>
@@ -301,7 +301,8 @@ public:<br>
 /// \c static_cast<int>(1.0).<br>
 class CXXStaticCastExpr final<br>
     : public CXXNamedCastExpr,<br>
-      private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> {<br>
+      private llvm::TrailingObjects<CXXStaticCastExpr, CastExpr::BasePathSizeTy,<br>
+                                    CXXBaseSpecifier *> {<br>
   CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,<br>
                     unsigned pathSize, TypeSourceInfo *writtenTy,<br>
                     SourceLocation l, SourceLocation RParenLoc,<br>
@@ -312,6 +313,10 @@ class CXXStaticCastExpr final<br>
   explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)<br>
       : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {}<br>
<br>
+  size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {<br>
+    return path_empty() ? 0 : 1;<br>
+  }<br>
+<br>
 public:<br>
   friend class CastExpr;<br>
   friend TrailingObjects;<br>
@@ -337,7 +342,8 @@ public:<br>
 /// check to determine how to perform the type conversion.<br>
 class CXXDynamicCastExpr final<br>
     : public CXXNamedCastExpr,<br>
-      private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {<br>
+      private llvm::TrailingObjects<<br>
+          CXXDynamicCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {<br>
   CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,<br>
                      Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,<br>
                      SourceLocation l, SourceLocation RParenLoc,<br>
@@ -348,6 +354,10 @@ class CXXDynamicCastExpr final<br>
   explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)<br>
       : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {}<br>
<br>
+  size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {<br>
+    return path_empty() ? 0 : 1;<br>
+  }<br>
+<br>
 public:<br>
   friend class CastExpr;<br>
   friend TrailingObjects;<br>
@@ -380,6 +390,7 @@ public:<br>
 class CXXReinterpretCastExpr final<br>
     : public CXXNamedCastExpr,<br>
       private llvm::TrailingObjects<CXXReinterpretCastExpr,<br>
+                                    CastExpr::BasePathSizeTy,<br>
                                     CXXBaseSpecifier *> {<br>
   CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,<br>
                          Expr *op, unsigned pathSize,<br>
@@ -392,6 +403,10 @@ class CXXReinterpretCastExpr final<br>
   CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)<br>
       : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {}<br>
<br>
+  size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {<br>
+    return path_empty() ? 0 : 1;<br>
+  }<br>
+<br>
 public:<br>
   friend class CastExpr;<br>
   friend TrailingObjects;<br>
@@ -419,7 +434,8 @@ public:<br>
 /// value.<br>
 class CXXConstCastExpr final<br>
     : public CXXNamedCastExpr,<br>
-      private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> {<br>
+      private llvm::TrailingObjects<CXXConstCastExpr, CastExpr::BasePathSizeTy,<br>
+                                    CXXBaseSpecifier *> {<br>
   CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,<br>
                    TypeSourceInfo *writtenTy, SourceLocation l,<br>
                    SourceLocation RParenLoc, SourceRange AngleBrackets)<br>
@@ -429,6 +445,10 @@ class CXXConstCastExpr final<br>
   explicit CXXConstCastExpr(EmptyShell Empty)<br>
       : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {}<br>
<br>
+  size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {<br>
+    return path_empty() ? 0 : 1;<br>
+  }<br>
+<br>
 public:<br>
   friend class CastExpr;<br>
   friend TrailingObjects;<br>
@@ -1471,7 +1491,8 @@ public:<br>
 /// \endcode<br>
 class CXXFunctionalCastExpr final<br>
     : public ExplicitCastExpr,<br>
-      private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> {<br>
+      private llvm::TrailingObjects<<br>
+          CXXFunctionalCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {<br>
   SourceLocation LParenLoc;<br>
   SourceLocation RParenLoc;<br>
<br>
@@ -1486,6 +1507,10 @@ class CXXFunctionalCastExpr final<br>
   explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)<br>
       : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {}<br>
<br>
+  size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {<br>
+    return path_empty() ? 0 : 1;<br>
+  }<br>
+<br>
 public:<br>
   friend class CastExpr;<br>
   friend TrailingObjects;<br>
<br>
Modified: cfe/trunk/include/clang/AST/ExprObjC.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=338489&r1=338488&r2=338489&view=diff" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=338489&r1=338488&r2=338489&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)<br>
+++ cfe/trunk/include/clang/AST/ExprObjC.h Tue Jul 31 23:06:16 2018<br>
@@ -1571,7 +1571,8 @@ public:<br>
 /// \endcode<br>
 class ObjCBridgedCastExpr final<br>
     : public ExplicitCastExpr,<br>
-      private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {<br>
+      private llvm::TrailingObjects<<br>
+          ObjCBridgedCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {<br>
   friend class ASTStmtReader;<br>
   friend class ASTStmtWriter;<br>
   friend class CastExpr;<br>
@@ -1581,6 +1582,10 @@ class ObjCBridgedCastExpr final<br>
   SourceLocation BridgeKeywordLoc;<br>
   unsigned Kind : 2;<br>
<br>
+  size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {<br>
+    return path_empty() ? 0 : 1;<br>
+  }<br>
+<br>
 public:<br>
   ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,<br>
                       CastKind CK, SourceLocation BridgeKeywordLoc,<br>
<br>
Modified: cfe/trunk/include/clang/AST/Stmt.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=338489&r1=338488&r2=338489&view=diff" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=338489&r1=338488&r2=338489&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/Stmt.h (original)<br>
+++ cfe/trunk/include/clang/AST/Stmt.h Tue Jul 31 23:06:16 2018<br>
@@ -204,7 +204,7 @@ protected:<br>
<br>
     unsigned Kind : 6;<br>
     unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.<br>
-    unsigned BasePathSize : 32 - 6 - 1 - NumExprBits;<br>
+    unsigned BasePathIsEmpty : 1;<br>
   };<br>
<br>
   class CallExprBitfields {<br>
<br>
Modified: cfe/trunk/lib/AST/Expr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=338489&r1=338488&r2=338489&view=diff" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=338489&r1=338488&r2=338489&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/Expr.cpp (original)<br>
+++ cfe/trunk/lib/AST/Expr.cpp Tue Jul 31 23:06:16 2018<br>
@@ -1734,6 +1734,21 @@ NamedDecl *CastExpr::getConversionFuncti<br>
   return nullptr;<br>
 }<br>
<br>
+CastExpr::BasePathSizeTy *CastExpr::BasePathSize() {<br>
+  assert(!path_empty());<br>
+  switch (getStmtClass()) {<br>
+#define ABSTRACT_STMT(x)<br>
+#define CASTEXPR(Type, Base)                                                   \<br>
+  case Stmt::Type##Class:                                                      \<br>
+    return static_cast<Type *>(this)                                           \<br>
+        ->getTrailingObjects<CastExpr::BasePathSizeTy>();<br>
+#define STMT(Type, Base)<br>
+#include "clang/AST/StmtNodes.inc"<br>
+  default:<br>
+    llvm_unreachable("non-cast expressions not possible here");<br>
+  }<br>
+}<br>
+<br>
 CXXBaseSpecifier **CastExpr::path_buffer() {<br>
   switch (getStmtClass()) {<br>
 #define ABSTRACT_STMT(x)<br>
@@ -1772,7 +1787,9 @@ ImplicitCastExpr *ImplicitCastExpr::Crea<br>
                                            const CXXCastPath *BasePath,<br>
                                            ExprValueKind VK) {<br>
   unsigned PathSize = (BasePath ? BasePath->size() : 0);<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   ImplicitCastExpr *E =<br>
     new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);<br>
   if (PathSize)<br>
@@ -1783,7 +1800,9 @@ ImplicitCastExpr *ImplicitCastExpr::Crea<br>
<br>
 ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(const ASTContext &C,<br>
                                                 unsigned PathSize) {<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize);<br>
 }<br>
<br>
@@ -1794,7 +1813,9 @@ CStyleCastExpr *CStyleCastExpr::Create(c<br>
                                        TypeSourceInfo *WrittenTy,<br>
                                        SourceLocation L, SourceLocation R) {<br>
   unsigned PathSize = (BasePath ? BasePath->size() : 0);<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   CStyleCastExpr *E =<br>
     new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R);<br>
   if (PathSize)<br>
@@ -1805,7 +1826,9 @@ CStyleCastExpr *CStyleCastExpr::Create(c<br>
<br>
 CStyleCastExpr *CStyleCastExpr::CreateEmpty(const ASTContext &C,<br>
                                             unsigned PathSize) {<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize);<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/ExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=338489&r1=338488&r2=338489&view=diff" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=338489&r1=338488&r2=338489&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Jul 31 23:06:16 2018<br>
@@ -559,7 +559,9 @@ CXXStaticCastExpr *CXXStaticCastExpr::Cr<br>
                                              SourceLocation RParenLoc,<br>
                                              SourceRange AngleBrackets) {<br>
   unsigned PathSize = (BasePath ? BasePath->size() : 0);<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   auto *E =<br>
       new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,<br>
                                      RParenLoc, AngleBrackets);<br>
@@ -571,7 +573,9 @@ CXXStaticCastExpr *CXXStaticCastExpr::Cr<br>
<br>
 CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(const ASTContext &C,<br>
                                                   unsigned PathSize) {<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);<br>
 }<br>
<br>
@@ -584,7 +588,9 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::<br>
                                                SourceLocation RParenLoc,<br>
                                                SourceRange AngleBrackets) {<br>
   unsigned PathSize = (BasePath ? BasePath->size() : 0);<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   auto *E =<br>
       new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,<br>
                                       RParenLoc, AngleBrackets);<br>
@@ -596,7 +602,9 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::<br>
<br>
 CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(const ASTContext &C,<br>
                                                     unsigned PathSize) {<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);<br>
 }<br>
<br>
@@ -641,7 +649,9 @@ CXXReinterpretCastExpr::Create(const AST<br>
                                SourceLocation RParenLoc,<br>
                                SourceRange AngleBrackets) {<br>
   unsigned PathSize = (BasePath ? BasePath->size() : 0);<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   auto *E =<br>
       new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,<br>
                                           RParenLoc, AngleBrackets);<br>
@@ -653,7 +663,9 @@ CXXReinterpretCastExpr::Create(const AST<br>
<br>
 CXXReinterpretCastExpr *<br>
 CXXReinterpretCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);<br>
 }<br>
<br>
@@ -676,7 +688,9 @@ CXXFunctionalCastExpr::Create(const ASTC<br>
                               const CXXCastPath *BasePath,<br>
                               SourceLocation L, SourceLocation R) {<br>
   unsigned PathSize = (BasePath ? BasePath->size() : 0);<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   auto *E =<br>
       new (Buffer) CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, L, R);<br>
   if (PathSize)<br>
@@ -687,7 +701,9 @@ CXXFunctionalCastExpr::Create(const ASTC<br>
<br>
 CXXFunctionalCastExpr *<br>
 CXXFunctionalCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {<br>
-  void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  void *Buffer =<br>
+      C.Allocate(totalSizeToAlloc<CastExpr::BasePathSizeTy, CXXBaseSpecifier *>(<br>
+          PathSize ? 1 : 0, PathSize));<br>
   return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);<br>
 }<br>
<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp?rev=338489&view=auto" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp?rev=338489&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp Tue Jul 31 23:06:16 2018<br>
@@ -0,0 +1,27 @@<br>
+// RUN: %clang_cc1 %s -emit-llvm -o -<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Please use -emit-llvm-only here rather than writing the IR to stdout.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+// <a href="https://bugs.llvm.org/show_bug.cgi?id=38356" rel="noreferrer noreferrer" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=38356</a><br>
+// We only check that we do not crash.<br>
+<br>
+template <typename a, a b(unsigned), int c, unsigned...><br>
+struct d : d<a, b, c - 1> {};<br>
+template <typename a, a b(unsigned), unsigned... e><br>
+struct d<a, b, 0, e...> {<br>
+  a f[0];<br>
+};<br>
+struct g {<br>
+  static g h(unsigned);<br>
+};<br>
+struct i {<br>
+  void j() const;<br>
+  // Current maximum depth of recursive template instantiation is 1024,<br>
+  // thus, this \/ threshold value is used here. BasePathSize in CastExpr might<br>
+  // not fit it, so we are testing that we do fit it.<br>
+  // If -ftemplate-depth= is provided, larger values (4096 and up) cause crashes<br>
+  // elsewhere.<br>
+  d<g, g::h, (1U << 10U) - 2U> f;<br>
+};<br>
+void i::j() const {<br>
+  const void *k{f.f};<br>
+  (void)k;<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" rel="noreferrer">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div>