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