From 6450af4a6a158ad37db5d7b5c1b982380d0dd54b Mon Sep 17 00:00:00 2001 From: Faisal Vali <faisalv@yahoo.com> Date: Mon, 1 Jan 2018 16:36:47 +0000 Subject: [PATCH] Use 'unsigned int' instead of enum bit-fields to silence some warnings from r321622 - bots were complaining that the bit-field width was less than the width of the underlying type (note, underlying types of enums can not be bit-fields) - add static_asserts for TSS and TSW to ensure that the bit-fields can hold all the enumerators - and add comments next to the last enumerator warning not to reorder. See https://reviews.llvm.org/rC321622 for the patch that introduced the warnings. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321625 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/TypeLoc.h | 13 ++++--- include/clang/Basic/Specifiers.h | 66 +++++++++++++++++++------------- lib/Sema/DeclSpec.cpp | 6 +-- 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index dca4fcffcb0..cdfb740f6b5 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -607,7 +607,7 @@ public: void setWrittenSignSpec(TypeSpecifierSign written) { if (needsExtraLocalData()) - getWrittenBuiltinSpecs().Sign = written; + getWrittenBuiltinSpecs().Sign = static_cast<unsigned char>(written); } TypeSpecifierWidth getWrittenWidthSpec() const { @@ -623,7 +623,7 @@ public: void setWrittenWidthSpec(TypeSpecifierWidth written) { if (needsExtraLocalData()) - getWrittenBuiltinSpecs().Width = written; + getWrittenBuiltinSpecs().Width = static_cast<unsigned char>(written); } TypeSpecifierType getWrittenTypeSpec() const; @@ -634,7 +634,7 @@ public: void setWrittenTypeSpec(TypeSpecifierType written) { if (needsExtraLocalData()) - getWrittenBuiltinSpecs().Type = written; + getWrittenBuiltinSpecs().Type = static_cast<unsigned char>(written); } bool hasModeAttr() const { @@ -653,9 +653,10 @@ public: setBuiltinLoc(Loc); if (needsExtraLocalData()) { WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); - wbs.Sign = TypeSpecifierSign::TSS_unspecified; - wbs.Width = TypeSpecifierWidth::TSW_unspecified; - wbs.Type = TypeSpecifierType::TST_unspecified; + wbs.Sign = static_cast<unsigned char>(TypeSpecifierSign::TSS_unspecified); + wbs.Width = + static_cast<unsigned char>(TypeSpecifierWidth::TSW_unspecified); + wbs.Type = static_cast<unsigned char>(TypeSpecifierType::TST_unspecified); wbs.ModeAttr = false; } } diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index 55b85997329..be12af9eaa7 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -26,16 +26,18 @@ namespace clang { TSW_unspecified, TSW_short, TSW_long, - TSW_longlong + TSW_longlong // This must be the last enumerator (see struct + // WrittenBuiltinSpecs below prior to reordering). }; /// \brief Specifies the signedness of a type, e.g., signed or unsigned. enum class TypeSpecifierSign : unsigned char { TSS_unspecified, TSS_signed, - TSS_unsigned + TSS_unsigned // This must be the last enumerator (see struct + // WrittenBuiltinSpecs below prior to reordering). }; - + enum TypeSpecifiersPipe { TSP_unspecified, TSP_pipe @@ -46,49 +48,61 @@ namespace clang { TST_unspecified, TST_void, TST_char, - TST_wchar, // C++ wchar_t - TST_char16, // C++11 char16_t - TST_char32, // C++11 char32_t + TST_wchar, // C++ wchar_t + TST_char16, // C++11 char16_t + TST_char32, // C++11 char32_t TST_int, TST_int128, - TST_half, // OpenCL half, ARM NEON __fp16 - TST_Float16, // C11 extension ISO/IEC TS 18661-3 + TST_half, // OpenCL half, ARM NEON __fp16 + TST_Float16, // C11 extension ISO/IEC TS 18661-3 TST_float, TST_double, TST_float128, - TST_bool, // _Bool - TST_decimal32, // _Decimal32 - TST_decimal64, // _Decimal64 - TST_decimal128, // _Decimal128 + TST_bool, // _Bool + TST_decimal32, // _Decimal32 + TST_decimal64, // _Decimal64 + TST_decimal128, // _Decimal128 TST_enum, TST_union, TST_struct, - TST_class, // C++ class type - TST_interface, // C++ (Microsoft-specific) __interface type - TST_typename, // Typedef, C++ class-name or enum name, etc. + TST_class, // C++ class type + TST_interface, // C++ (Microsoft-specific) __interface type + TST_typename, // Typedef, C++ class-name or enum name, etc. TST_typeofType, TST_typeofExpr, - TST_decltype, // C++11 decltype - TST_underlyingType, // __underlying_type for C++11 - TST_auto, // C++11 auto - TST_decltype_auto, // C++1y decltype(auto) - TST_auto_type, // __auto_type extension - TST_unknown_anytype, // __unknown_anytype extension - TST_atomic, // C11 _Atomic + TST_decltype, // C++11 decltype + TST_underlyingType, // __underlying_type for C++11 + TST_auto, // C++11 auto + TST_decltype_auto, // C++1y decltype(auto) + TST_auto_type, // __auto_type extension + TST_unknown_anytype, // __unknown_anytype extension + TST_atomic, // C11 _Atomic #define GENERIC_IMAGE_TYPE(ImgType, Id) TST_##ImgType##_t, // OpenCL image types #include "clang/Basic/OpenCLImageTypes.def" - TST_error // erroneous type + TST_error // erroneous type -- Additionally, this must be the last + // enumerator (see struct WrittenBuiltinSpecs below prior to + // reordering). }; /// \brief Structure that packs information about the type specifiers that /// were written in a particular type specifier sequence. struct WrittenBuiltinSpecs { + static_assert(static_cast<unsigned int>(TypeSpecifierType::TST_error) < (1 << 6), "Type bitfield not wide enough for TST"); - /*DeclSpec::TST*/ TypeSpecifierType Type : 6; - /*DeclSpec::TSS*/ TypeSpecifierSign Sign : 2; - /*DeclSpec::TSW*/ TypeSpecifierWidth Width : 2; + /*DeclSpec::TST*/ unsigned Type : 6; + + static_assert(static_cast<unsigned int>(TypeSpecifierSign::TSS_unsigned) < + (1 << 2), + "Type bitfield not wide enough for TSS"); + /*DeclSpec::TSS*/ unsigned Sign : 2; + + static_assert(static_cast<unsigned int>(TypeSpecifierWidth::TSW_longlong) < + (1 << 2), + "Type bitfield not wide enough for TSW"); + /*DeclSpec::TSW*/ unsigned Width : 2; + unsigned ModeAttr : 1; }; diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 69266933d6d..c76d94e7d80 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -972,9 +972,9 @@ bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, } void DeclSpec::SaveWrittenBuiltinSpecs() { - writtenBS.Sign = getTypeSpecSign(); - writtenBS.Width = getTypeSpecWidth(); - writtenBS.Type = getTypeSpecType(); + writtenBS.Sign = static_cast<unsigned char>(getTypeSpecSign()); + writtenBS.Width = static_cast<unsigned char>(getTypeSpecWidth()); + writtenBS.Type = static_cast<unsigned char>(getTypeSpecType()); // Search the list of attributes for the presence of a mode attribute. writtenBS.ModeAttr = false; AttributeList* attrs = getAttributes().getList(); -- GitLab