r247618 - C11 _Bool bitfield diagnostic

Rachel Craik via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 14 19:07:51 PDT 2015


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 <thakis at chromium.org>
To:	Richard Smith <richard at metafoo.co.uk>
Cc:	Rachel Craik/Toronto/IBM at IBMCA, cfe-commits
            <cfe-commits at lists.llvm.org>
Date:	09/14/2015 09:53 PM
Subject:	Re: r247618 - C11 _Bool bitfield diagnostic
Sent by:	thakis at google.com



On Mon, Sep 14, 2015 at 5:28 PM, Richard Smith <richard at metafoo.co.uk>
wrote:
  On Mon, Sep 14, 2015 at 5:18 PM, Nico Weber via cfe-commits <
  cfe-commits at 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 at 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 at lists.llvm.org
     http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


   _______________________________________________
   cfe-commits mailing list
   cfe-commits at lists.llvm.org
   http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150914/423bb4c8/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: graycol.gif
Type: image/gif
Size: 105 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150914/423bb4c8/attachment-0001.gif>


More information about the cfe-commits mailing list