Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -2790,6 +2790,10 @@ private: Stmt *Op; + // BasePathSize needs to have width of 9 bits (or more, up to 14(?) bits), + // so it does not fit into CastExprBitfields, where we only have 8 bits left. + unsigned BasePathSize : 14; + bool CastConsistency() const; const CXXBaseSpecifier * const *path_buffer() const { @@ -2798,9 +2802,9 @@ CXXBaseSpecifier **path_buffer(); void setBasePathSize(unsigned basePathSize) { - CastExprBits.BasePathSize = basePathSize; - assert(CastExprBits.BasePathSize == basePathSize && - "basePathSize doesn't fit in bits of CastExprBits.BasePathSize!"); + BasePathSize = basePathSize; + assert(BasePathSize == basePathSize && + "basePathSize doesn't fit in bits of BasePathSize!"); } protected: @@ -2859,8 +2863,8 @@ 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 BasePathSize == 0; } + unsigned path_size() const { return 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(); } Index: include/clang/AST/Stmt.h =================================================================== --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -204,7 +204,6 @@ unsigned Kind : 6; unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr. - unsigned BasePathSize : 32 - 6 - 1 - NumExprBits; }; class CallExprBitfields { Index: test/CodeGenCXX/castexpr-basepathsize-threshold.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/castexpr-basepathsize-threshold.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +// https://bugs.llvm.org/show_bug.cgi?id=38356 +// We only check that we do not crash. + +template +struct d : d {}; +template +struct d { + 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 f; +}; +void i::j() const { + const void *k{f.f}; + (void)k; +}