Index: clang/include/clang/Basic/DiagnosticGroups.td =================================================================== --- clang/include/clang/Basic/DiagnosticGroups.td +++ clang/include/clang/Basic/DiagnosticGroups.td @@ -487,6 +487,7 @@ def ObjCMultipleMethodNames : DiagGroup<"objc-multiple-method-names">; def ObjCFlexibleArray : DiagGroup<"objc-flexible-array">; def ObjCBoxing : DiagGroup<"objc-boxing">; +def ObjCBoolBitfield : DiagGroup<"objc-bool-bitfield">; def OpenCLUnsupportedRGBA: DiagGroup<"opencl-unsupported-rgba">; def UnderalignedExceptionObject : DiagGroup<"underaligned-exception-object">; def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">; @@ -929,6 +930,7 @@ ObjCMissingSuperCalls, ObjCDesignatedInit, ObjCFlexibleArray, + ObjCBoolBitfield, OverloadedVirtual, PrivateExtern, SelTypeCast, Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5892,6 +5892,9 @@ " %select{struct|interface|union|class|enum}2">; def err_objc_variable_sized_type_not_at_end : Error< "field %0 with variable sized type %1 is not at the end of class">; +def warn_objc_bool_bitfield_has_width_one : Warning<"BOOL bit-field %0 with " + " width 1 can not store BOOL's YES value. Change the bitfield type to " + "'unsigned' to silence this warning.">, InGroup; def note_next_field_declaration : Note< "next field declaration is here">; def note_next_ivar_declaration : Note< Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -16513,6 +16513,12 @@ << FieldName << Value.toString(10) << (unsigned)TypeWidth; } + + // If Objective C's BOOL type is a signed char (or any signed integer), then + // 1 bit is not wide enough to store Objective-C's YES(1) value. + if (LangOpts.ObjC && Value == 1 && NSAPIObj->isObjCBOOLType(FieldTy) && + FieldTy->isSignedIntegerType()) + Diag(FieldLoc, diag::warn_objc_bool_bitfield_has_width_one) << FieldName; } return BitWidth; Index: clang/test/Misc/warning-wall.c =================================================================== --- clang/test/Misc/warning-wall.c +++ clang/test/Misc/warning-wall.c @@ -78,6 +78,7 @@ CHECK-NEXT: -Wobjc-missing-super-calls CHECK-NEXT: -Wobjc-designated-initializers CHECK-NEXT: -Wobjc-flexible-array +CHECK-NEXT: -Wobjc-bool-bitfield CHECK-NEXT: -Woverloaded-virtual CHECK-NEXT: -Wprivate-extern CHECK-NEXT: -Wcast-of-sel-type Index: clang/test/Sema/bitfield.c =================================================================== --- clang/test/Sema/bitfield.c +++ clang/test/Sema/bitfield.c @@ -1,5 +1,7 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -std=c11 -Wno-unused-value +typedef signed char BOOL; + enum e0; // expected-note{{forward declaration of 'enum e0'}} struct a { @@ -28,6 +30,9 @@ _Bool : 2; // expected-error {{width of anonymous bit-field (2 bits) exceeds width of its type (1 bit)}} _Bool h : 5; // expected-error {{width of bit-field 'h' (5 bits) exceeds width of its type (1 bit)}} + + // Make sure this doesn't trigger Objective-C's BOOL bitfield warning. + BOOL i : 1; }; struct b {unsigned x : 2;} x; Index: clang/test/SemaObjC/class-bool-bitfield.m =================================================================== --- /dev/null +++ clang/test/SemaObjC/class-bool-bitfield.m @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 %s -fobjc-runtime=macosx-fragile-10.5 -fsyntax-only -verify=signed +// RUN: %clang_cc1 %s -DBOOL_IS_BOOL -fobjc-runtime=macosx-fragile-10.5 -fsyntax-only -verify=bool + +#ifdef BOOL_IS_BOOL +// If BOOL is _Bool then bitfields with a width of 1 are fine. +typedef _Bool BOOL; +#else +typedef signed char BOOL; +#endif + +typedef BOOL BOOL_TYPEDEF; + +@interface X { + // If BOOL is a signed char then a 1-bit field isn't wide enough to store + // YES(1). + BOOL f : 1; // signed-warning {{BOOL bit-field 'f' with width 1 can not store BOOL's YES value.}} + BOOL_TYPEDEF g : 1; // signed-warning {{BOOL bit-field 'g' with width 1 can not store BOOL's YES value.}} + // Only warn if Objective-C's BOOL type or a typedef for it is used. + signed char h : 1; + // A width of 2 or more can store YES and NO. + BOOL i : 2; // bool-error {{exceeds width of its type}} + BOOL j : 3; // bool-error {{exceeds width of its type}} +} +@end + +struct S { + BOOL f : 1; // signed-warning {{BOOL bit-field 'f' with width 1 can not store BOOL's YES value.}} +};