diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1624,6 +1624,9 @@ /// Whether this function has extended parameter information. unsigned HasExtParameterInfos : 1; + /// Whether this function has extra bitfields for the prototype. + unsigned HasExtraBitfields : 1; + /// Whether the function is variadic. unsigned Variadic : 1; @@ -3798,13 +3801,12 @@ /// A simple holder for various uncommon bits which do not fit in /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the - /// alignment of subsequent objects in TrailingObjects. You must update - /// hasExtraBitfields in FunctionProtoType after adding extra data here. + /// alignment of subsequent objects in TrailingObjects. struct alignas(void *) FunctionTypeExtraBitfields { /// The number of types in the exception specification. /// A whole unsigned is not needed here and according to /// [implimits] 8 bits would be enough here. - unsigned NumExceptionType; + unsigned NumExceptionType = 0; }; protected: @@ -3998,6 +4000,10 @@ Result.ExceptionSpec = ESI; return Result; } + + bool requiresFunctionProtoTypeExtraBitfields() const { + return ExceptionSpec.Type == EST_Dynamic; + } }; private: @@ -4088,16 +4094,13 @@ return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions()); } - /// Whether the trailing FunctionTypeExtraBitfields is present. - static bool hasExtraBitfields(ExceptionSpecificationType EST) { - // If the exception spec type is EST_Dynamic then we have > 0 exception - // types and the exact number is stored in FunctionTypeExtraBitfields. - return EST == EST_Dynamic; - } - /// Whether the trailing FunctionTypeExtraBitfields is present. bool hasExtraBitfields() const { - return hasExtraBitfields(getExceptionSpecType()); + assert((getExceptionSpecType() != EST_Dynamic || + FunctionTypeBits.HasExtraBitfields) && + "ExtraBitfields are required for given ExceptionSpecType"); + return FunctionTypeBits.HasExtraBitfields; + } bool hasExtQualifiers() const { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4451,8 +4451,7 @@ QualType, SourceLocation, FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType, Expr *, FunctionDecl *, FunctionProtoType::ExtParameterInfo, Qualifiers>( - NumArgs, EPI.Variadic, - FunctionProtoType::hasExtraBitfields(EPI.ExceptionSpec.Type), + NumArgs, EPI.Variadic, EPI.requiresFunctionProtoTypeExtraBitfields(), ESH.NumExceptionType, ESH.NumExprPtr, ESH.NumFunctionDeclPtr, EPI.ExtParameterInfos ? NumArgs : 0, EPI.TypeQuals.hasNonFastQualifiers() ? 1 : 0); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3213,12 +3213,15 @@ FunctionTypeBits.Variadic = epi.Variadic; FunctionTypeBits.HasTrailingReturn = epi.HasTrailingReturn; - // Fill in the extra trailing bitfields if present. - if (hasExtraBitfields(epi.ExceptionSpec.Type)) { + if (epi.requiresFunctionProtoTypeExtraBitfields()) { + FunctionTypeBits.HasExtraBitfields = true; auto &ExtraBits = *getTrailingObjects(); - ExtraBits.NumExceptionType = epi.ExceptionSpec.Exceptions.size(); + ExtraBits = FunctionTypeExtraBitfields(); + } else { + FunctionTypeBits.HasExtraBitfields = false; } + // Fill in the trailing argument array. auto *argSlot = getTrailingObjects(); for (unsigned i = 0; i != getNumParams(); ++i) { @@ -3229,6 +3232,9 @@ // Fill in the exception type array if present. if (getExceptionSpecType() == EST_Dynamic) { + auto &ExtraBits = *getTrailingObjects(); + ExtraBits.NumExceptionType = epi.ExceptionSpec.Exceptions.size(); + assert(hasExtraBitfields() && "missing trailing extra bitfields!"); auto *exnSlot = reinterpret_cast(getTrailingObjects());