r338489 - [AST] CastExpr: BasePathSize is not large enough.
Roman Lebedev via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 1 14:21:20 PDT 2018
r338640
On Wed, Aug 1, 2018 at 8:38 PM, Roman Lebedev <lebedev.ri at gmail.com> wrote:
> On Wed, Aug 1, 2018 at 8:36 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>> On Tue, 31 Jul 2018, 23:06 Roman Lebedev via cfe-commits,
>> <cfe-commits at 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 at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list