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