As of DR262, the C standard clarified that the width of a bit-field can not exceed that of the specified type, and this change was primarily to ensure that Clang correctly enforced this part of the standard. Looking at the C+ +11 standard again, it states that although the specified width of a bit-field may exceed the number of bits in the object representation (which includes padding bits) of the specified type, the extra bits will not take any part in the bit-field's value representation.
Taking this into account, it seems that the correct way to validate the width of a bit-field (ignoring the special case of MS in C mode) would be to use getIntWidth in C mode, and getTypeSize in C++ mode. I would be happy create a patch to make this change tomorrow if people are in agreement. Rachel From: Nico Weber <tha...@chromium.org> To: Richard Smith <rich...@metafoo.co.uk> Cc: Rachel Craik/Toronto/IBM@IBMCA, cfe-commits <cfe-commits@lists.llvm.org> Date: 09/14/2015 09:53 PM Subject: Re: r247618 - C11 _Bool bitfield diagnostic Sent by: tha...@google.com On Mon, Sep 14, 2015 at 5:28 PM, Richard Smith <rich...@metafoo.co.uk> wrote: On Mon, Sep 14, 2015 at 5:18 PM, Nico Weber via cfe-commits < cfe-commits@lists.llvm.org> wrote: This also fires for bool in C++ files, even though the commit message saying C11 and _Bool. Given the test changes, I suppose that's intentional? This fires a lot on existing code, for example protobuf: ../../third_party/protobuf/src/google/protobuf/extension_set.h:465:10: error: width of bit-field 'is_cleared' (4 bits) exceeds the width of its type; value will be truncated to 1 bit [-Werror,-Wbitfield-width] bool is_cleared : 4; ^ ../../third_party/protobuf/src/google/protobuf/extension_set.h:472:10: error: width of bit-field 'is_lazy' (4 bits) exceeds the width of its type; value will be truncated to 1 bit [-Werror,-Wbitfield-width] bool is_lazy : 4; ^ Is this expected? Is this a behavior change, or did the truncation happen previously and it's now just getting warned on? The code previously assumed that MSVC used the C rules here; it appears that's not true in all cases. This was on a Mac bot? Can we just remove the " || IsMsStruct || Context.getTargetInfo ().getCXXABI().isMicrosoft()"? Is there some reason we need to prohibit overwide bitfields for MS bitfield layout, rather than just warning on them? (Does record layout fail somehow?) On Mon, Sep 14, 2015 at 2:27 PM, Rachel Craik via cfe-commits < cfe-commits@lists.llvm.org> wrote: Author: rcraik Date: Mon Sep 14 16:27:36 2015 New Revision: 247618 URL: http://llvm.org/viewvc/llvm-project?rev=247618&view=rev Log: C11 _Bool bitfield diagnostic Summary: Implement DR262 (for C). This patch will mainly affect bitfields of type _Bool Reviewers: fraggamuffin, rsmith Subscribers: hubert.reinterpretcast, cfe-commits Differential Revision: http://reviews.llvm.org/D10018 Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CodeGen/bitfield-2.c cfe/trunk/test/CodeGenCXX/warn-padded-packed.cpp cfe/trunk/test/Misc/warning-flags.c cfe/trunk/test/Sema/bitfield.c cfe/trunk/test/SemaCXX/bitfield-layout.cpp cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp cfe/trunk/test/SemaCXX/ms_wide_bitfield.cpp cfe/trunk/test/SemaObjC/class-bitfield.m Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Mon Sep 14 16:27:36 2015 @@ -32,6 +32,7 @@ def AutoImport : DiagGroup<"auto-import" def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">; def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">; def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">; +def BitFieldWidth : DiagGroup<"bitfield-width">; def ConstantConversion : DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >; def LiteralConversion : DiagGroup<"literal-conversion">; Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Sep 14 16:27:36 2015 @@ -4314,20 +4314,21 @@ def err_bitfield_has_negative_width : Er def err_anon_bitfield_has_negative_width : Error< "anonymous bit-field has negative width (%0)">; def err_bitfield_has_zero_width : Error<"named bit-field %0 has zero width">; -def err_bitfield_width_exceeds_type_size : Error< - "size of bit-field %0 (%1 bits) exceeds size of its type (%2 bits)">; -def err_anon_bitfield_width_exceeds_type_size : Error< - "size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)">; +def err_bitfield_width_exceeds_type_width : Error< + "width of bit-field %0 (%1 bits) exceeds width of its type (%2 bit%s2)">; +def err_anon_bitfield_width_exceeds_type_width : Error< + "width of anonymous bit-field (%0 bits) exceeds width of its type " + "(%1 bit%s1)">; def err_incorrect_number_of_vector_initializers : Error< "number of elements must be either one or match the size of the vector">; // Used by C++ which allows bit-fields that are wider than the type. -def warn_bitfield_width_exceeds_type_size: Warning< - "size of bit-field %0 (%1 bits) exceeds the size of its type; value will be " - "truncated to %2 bits">; -def warn_anon_bitfield_width_exceeds_type_size : Warning< - "size of anonymous bit-field (%0 bits) exceeds size of its type; value will " - "be truncated to %1 bits">; +def warn_bitfield_width_exceeds_type_width: Warning< + "width of bit-field %0 (%1 bits) exceeds the width of its type; value will " + "be truncated to %2 bit%s2">, InGroup<BitFieldWidth>; +def warn_anon_bitfield_width_exceeds_type_width : Warning< + "width of anonymous bit-field (%0 bits) exceeds width of its type; value " + "will be truncated to %1 bit%s1">, InGroup<BitFieldWidth>; def warn_missing_braces : Warning< "suggest braces around initialization of subobject">, Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Sep 14 16:27:36 2015 @@ -12625,26 +12625,26 @@ ExprResult Sema::VerifyBitField(SourceLo } if (!FieldTy->isDependentType()) { - uint64_t TypeSize = Context.getTypeSize(FieldTy); - if (Value.getZExtValue() > TypeSize) { + uint64_t TypeWidth = Context.getIntWidth(FieldTy); + if (Value.ugt(TypeWidth)) { if (!getLangOpts().CPlusPlus || IsMsStruct || Context.getTargetInfo().getCXXABI().isMicrosoft()) { if (FieldName) - return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) + return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width) << FieldName << (unsigned)Value.getZExtValue() - << (unsigned)TypeSize; + << (unsigned)TypeWidth; - return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_size) - << (unsigned)Value.getZExtValue() << (unsigned)TypeSize; + return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_width) + << (unsigned)Value.getZExtValue() << (unsigned)TypeWidth; } if (FieldName) - Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_size) + Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width) << FieldName << (unsigned)Value.getZExtValue() - << (unsigned)TypeSize; + << (unsigned)TypeWidth; else - Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_size) - << (unsigned)Value.getZExtValue() << (unsigned)TypeSize; + Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_width) + << (unsigned)Value.getZExtValue() << (unsigned)TypeWidth; } } Modified: cfe/trunk/test/CodeGen/bitfield-2.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/bitfield-2.c?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/bitfield-2.c (original) +++ cfe/trunk/test/CodeGen/bitfield-2.c Mon Sep 14 16:27:36 2015 @@ -237,7 +237,7 @@ unsigned long long test_5() { /***/ struct s6 { - _Bool f0 : 2; + unsigned f0 : 2; }; struct s6 g6 = { 0xF }; Modified: cfe/trunk/test/CodeGenCXX/warn-padded-packed.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/warn-padded-packed.cpp?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/warn-padded-packed.cpp (original) +++ cfe/trunk/test/CodeGenCXX/warn-padded-packed.cpp Mon Sep 14 16:27:36 2015 @@ -69,7 +69,7 @@ struct S12 { struct S13 { // expected-warning {{padding size of 'S13' with 6 bits to alignment boundary}} char c; - bool b : 10; // expected-warning {{size of bit-field 'b' (10 bits) exceeds the size of its type}} + bool b : 10; // expected-warning {{width of bit-field 'b' (10 bits) exceeds the width of its type}} }; // The warnings are emitted when the layout of the structs is computed, so we have to use them. Modified: cfe/trunk/test/Misc/warning-flags.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/warning-flags.c?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/Misc/warning-flags.c (original) +++ cfe/trunk/test/Misc/warning-flags.c Mon Sep 14 16:27:36 2015 @@ -18,7 +18,7 @@ This test serves two purposes: The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (92): +CHECK: Warnings without flags (90): CHECK-NEXT: ext_excess_initializers CHECK-NEXT: ext_excess_initializers_in_char_array_initializer CHECK-NEXT: ext_expected_semi_decl_list @@ -44,10 +44,8 @@ CHECK-NEXT: pp_pragma_once_in_main_fil CHECK-NEXT: pp_pragma_sysheader_in_main_file CHECK-NEXT: w_asm_qualifier_ignored CHECK-NEXT: warn_accessor_property_type_mismatch -CHECK-NEXT: warn_anon_bitfield_width_exceeds_type_size CHECK-NEXT: warn_arcmt_nsalloc_realloc CHECK-NEXT: warn_asm_label_on_auto_decl -CHECK-NEXT: warn_bitfield_width_exceeds_type_size CHECK-NEXT: warn_c_kext CHECK-NEXT: warn_call_to_pure_virtual_member_function_from_ctor_dtor CHECK-NEXT: warn_call_wrong_number_of_arguments Modified: cfe/trunk/test/Sema/bitfield.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/bitfield.c?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/Sema/bitfield.c (original) +++ cfe/trunk/test/Sema/bitfield.c Mon Sep 14 16:27:36 2015 @@ -6,7 +6,7 @@ struct a { int a : -1; // expected-error{{bit-field 'a' has negative width}} // rdar://6081627 - int b : 33; // expected-error{{size of bit-field 'b' (33 bits) exceeds size of its type (32 bits)}} + int b : 33; // expected-error{{width of bit-field 'b' (33 bits) exceeds width of its type (32 bits)}} int c : (1 + 0.25); // expected-error{{expression is not an integer constant expression}} int d : (int)(1 + 0.25); @@ -22,9 +22,12 @@ struct a { int g : (_Bool)1; // PR4017 - char : 10; // expected-error {{size of anonymous bit-field (10 bits) exceeds size of its type (8 bits)}} + char : 10; // expected-error {{width of anonymous bit-field (10 bits) exceeds width of its type (8 bits)}} unsigned : -2; // expected-error {{anonymous bit-field has negative width (-2)}} float : 12; // expected-error {{anonymous bit-field has non-integral type 'float'}} + + _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)}} }; struct b {unsigned x : 2;} x; Modified: cfe/trunk/test/SemaCXX/bitfield-layout.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/bitfield-layout.cpp?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/bitfield-layout.cpp (original) +++ cfe/trunk/test/SemaCXX/bitfield-layout.cpp Mon Sep 14 16:27:36 2015 @@ -5,25 +5,25 @@ // Simple tests. struct Test1 { - char c : 9; // expected-warning {{size of bit-field 'c' (9 bits) exceeds the size of its type; value will be truncated to 8 bits}} + char c : 9; // expected-warning {{width of bit-field 'c' (9 bits) exceeds the width of its type; value will be truncated to 8 bits}} }; CHECK_SIZE(Test1, 2); CHECK_ALIGN(Test1, 1); struct Test2 { - char c : 16; // expected-warning {{size of bit-field 'c' (16 bits) exceeds the size of its type; value will be truncated to 8 bits}} + char c : 16; // expected-warning {{width of bit-field 'c' (16 bits) exceeds the width of its type; value will be truncated to 8 bits}} }; CHECK_SIZE(Test2, 2); CHECK_ALIGN(Test2, 2); struct Test3 { - char c : 32; // expected-warning {{size of bit-field 'c' (32 bits) exceeds the size of its type; value will be truncated to 8 bits}} + char c : 32; // expected-warning {{width of bit-field 'c' (32 bits) exceeds the width of its type; value will be truncated to 8 bits}} }; CHECK_SIZE(Test3, 4); CHECK_ALIGN(Test3, 4); struct Test4 { - char c : 64; // expected-warning {{size of bit-field 'c' (64 bits) exceeds the size of its type; value will be truncated to 8 bits}} + char c : 64; // expected-warning {{width of bit-field 'c' (64 bits) exceeds the width of its type; value will be truncated to 8 bits}} }; CHECK_SIZE(Test4, 8); CHECK_ALIGN(Test4, 8); Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original) +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Mon Sep 14 16:27:36 2015 @@ -1801,9 +1801,9 @@ namespace Bitfields { bool b : 1; unsigned u : 5; int n : 5; - bool b2 : 3; - unsigned u2 : 74; // expected-warning {{exceeds the size of its type}} - int n2 : 81; // expected-warning {{exceeds the size of its type}} + bool b2 : 3; // expected-warning {{exceeds the width of its type}} + unsigned u2 : 74; // expected-warning {{exceeds the width of its type}} + int n2 : 81; // expected-warning {{exceeds the width of its type}} }; constexpr A a = { false, 33, 31, false, 0xffffffff, 0x7fffffff }; // expected-warning 2{{truncation}} Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp (original) +++ cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp Mon Sep 14 16:27:36 2015 @@ -872,7 +872,7 @@ namespace Lifetime { namespace Bitfields { struct A { - bool b : 3; + bool b : 1; int n : 4; unsigned u : 5; }; Modified: cfe/trunk/test/SemaCXX/ms_wide_bitfield.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ms_wide_bitfield.cpp?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/ms_wide_bitfield.cpp (original) +++ cfe/trunk/test/SemaCXX/ms_wide_bitfield.cpp Mon Sep 14 16:27:36 2015 @@ -1,9 +1,10 @@ // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -mms-bitfields -verify %s 2>&1 struct A { - char a : 9; // expected-error{{size of bit-field 'a' (9 bits) exceeds size of its type (8 bits)}} - int b : 33; // expected-error{{size of bit-field 'b' (33 bits) exceeds size of its type (32 bits)}} - bool c : 9; // expected-error{{size of bit-field 'c' (9 bits) exceeds size of its type (8 bits)}} + char a : 9; // expected-error{{width of bit-field 'a' (9 bits) exceeds width of its type (8 bits)}} + int b : 33; // expected-error{{width of bit-field 'b' (33 bits) exceeds width of its type (32 bits)}} + bool c : 9; // expected-error{{width of bit-field 'c' (9 bits) exceeds width of its type (1 bit)}} + bool d : 3; // expected-error{{width of bit-field 'd' (3 bits) exceeds width of its type (1 bit)}} }; int a[sizeof(A) == 1 ? 1 : -1]; Modified: cfe/trunk/test/SemaObjC/class-bitfield.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/class-bitfield.m?rev=247618&r1=247617&r2=247618&view=diff ============================================================================== --- cfe/trunk/test/SemaObjC/class-bitfield.m (original) +++ cfe/trunk/test/SemaObjC/class-bitfield.m Mon Sep 14 16:27:36 2015 @@ -5,7 +5,7 @@ int a : -1; // expected-error{{bit-field 'a' has negative width}} // rdar://6081627 - int b : 33; // expected-error{{size of bit-field 'b' (33 bits) exceeds size of its type (32 bits)}} + int b : 33; // expected-error{{width of bit-field 'b' (33 bits) exceeds width of its type (32 bits)}} int c : (1 + 0.25); // expected-error{{expression is not an integer constant expression}} int d : (int)(1 + 0.25); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits