Author: rnk Date: Mon Mar 13 17:33:04 2017 New Revision: 297680 URL: http://llvm.org/viewvc/llvm-project?rev=297680&view=rev Log: Widen AST bitfields too small to represent all enumerators
All of these were found by a new warning that I am prototyping, -Wbitfield-enum-conversion. Stmt::ExprBits::ObjectKind - This was not wide enough to represent OK_ObjSubscript, so this was a real, true positive bug. ObjCDeclSpec::objCDeclQualifier - On Windows, setting DQ_CSNullability would cause the bitfield to become negative because enum types are always implicitly 'int' there. This would probably never be noticed because this is a flag-style enum, so we only ever test one bit at a time. Switching to 'unsigned' also makes this type pack smaller on Windows. FunctionDecl::SClass - Technically, we only need two bits for all valid function storage classes. Functions can never have automatic or register storage class. This seems a bit too clever, and we have a bit to spare, so widening the bitfield seems like the best way to pacify the warning. You could classify this as a false positive, but widening the bitfield defends us from invalid ASTs. Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/AST/Expr.h cfe/trunk/include/clang/AST/Stmt.h cfe/trunk/include/clang/Sema/DeclSpec.h Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=297680&r1=297679&r2=297680&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Mon Mar 13 17:33:04 2017 @@ -1605,7 +1605,7 @@ private: // FIXME: This can be packed into the bitfields in DeclContext. // NOTE: VC++ packs bitfields poorly if the types differ. - unsigned SClass : 2; + unsigned SClass : 3; unsigned IsInline : 1; unsigned IsInlineSpecified : 1; protected: Modified: cfe/trunk/include/clang/AST/Expr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=297680&r1=297679&r2=297680&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Expr.h (original) +++ cfe/trunk/include/clang/AST/Expr.h Mon Mar 13 17:33:04 2017 @@ -115,6 +115,7 @@ protected: ExprBits.InstantiationDependent = ID; ExprBits.ValueKind = VK; ExprBits.ObjectKind = OK; + assert(ExprBits.ObjectKind == OK && "truncated kind"); ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; setType(T); } Modified: cfe/trunk/include/clang/AST/Stmt.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=297680&r1=297679&r2=297680&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Stmt.h (original) +++ cfe/trunk/include/clang/AST/Stmt.h Mon Mar 13 17:33:04 2017 @@ -127,13 +127,13 @@ protected: unsigned : NumStmtBits; unsigned ValueKind : 2; - unsigned ObjectKind : 2; + unsigned ObjectKind : 3; unsigned TypeDependent : 1; unsigned ValueDependent : 1; unsigned InstantiationDependent : 1; unsigned ContainsUnexpandedParameterPack : 1; }; - enum { NumExprBits = 16 }; + enum { NumExprBits = 17 }; class CharacterLiteralBitfields { friend class CharacterLiteral; @@ -350,6 +350,8 @@ protected: public: Stmt(StmtClass SC) { + static_assert(sizeof(*this) == sizeof(void *), + "changing bitfields changed sizeof(Stmt)"); static_assert(sizeof(*this) % alignof(void *) == 0, "Insufficient alignment!"); StmtBits.sClass = SC; Modified: cfe/trunk/include/clang/Sema/DeclSpec.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=297680&r1=297679&r2=297680&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) +++ cfe/trunk/include/clang/Sema/DeclSpec.h Mon Mar 13 17:33:04 2017 @@ -819,7 +819,9 @@ public: : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr), Nullability(0), GetterName(nullptr), SetterName(nullptr) { } - ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; } + ObjCDeclQualifier getObjCDeclQualifier() const { + return (ObjCDeclQualifier)objcDeclQualifier; + } void setObjCDeclQualifier(ObjCDeclQualifier DQVal) { objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal); } @@ -869,7 +871,7 @@ private: // FIXME: These two are unrelated and mutually exclusive. So perhaps // we can put them in a union to reflect their mutual exclusivity // (space saving is negligible). - ObjCDeclQualifier objcDeclQualifier : 7; + unsigned objcDeclQualifier : 7; // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind unsigned PropertyAttributes : 15; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits