rcraik updated this revision to Diff 34339.
rcraik added a comment.
I've updated the message to make it a bit clearer that this is a portability
concern. Are there any further concerns with this patch?
http://reviews.llvm.org/D10018
Files:
include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/Misc/warning-flags.c
test/Sema/c11-bitfield-width.c
Index: test/Sema/c11-bitfield-width.c
===================================================================
--- test/Sema/c11-bitfield-width.c
+++ test/Sema/c11-bitfield-width.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c11
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c99
+
+struct A {
+ _Bool : 0; // ok
+ _Bool : 3; // expected-warning {{size of anonymous bit-field (3 bits) exceeds the minimum width required to represent all valid values of that bit-field type}}
+ _Bool : 5; // expected-warning {{size of anonymous bit-field (5 bits) exceeds the minimum width required to represent all valid values of that bit-field type}}
+ _Bool : 7; // expected-warning {{size of anonymous bit-field (7 bits) exceeds the minimum width required to represent all valid values of that bit-field type}}
+ _Bool a : 1; // ok
+ _Bool b : 2; // expected-warning {{size of bit-field 'b' (2 bits) exceeds the minimum width required to represent all valid values of that bit-field type}}
+ _Bool c : 4; // expected-warning {{size of bit-field 'c' (4 bits) exceeds the minimum width required to represent all valid values of that bit-field type}}
+ _Bool d : 8; // expected-warning {{size of bit-field 'd' (8 bits) exceeds the minimum width required to represent all valid values of that bit-field type}}
+};
Index: test/Misc/warning-flags.c
===================================================================
--- test/Misc/warning-flags.c
+++ test/Misc/warning-flags.c
@@ -18,7 +18,7 @@
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_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
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -12604,6 +12604,20 @@
Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_size)
<< (unsigned)Value.getZExtValue() << (unsigned)TypeSize;
}
+ // C11 6.7.2.1p4 + footnote 122/C99 6.7.2.1p3 - the width of a bitfield
+ // of type _Bool may be erroneous if it exceeds 1 bit.
+ // Warn about _Bool bitfields > 1 bit as they will not be portable across
+ // different platforms
+ if ((getLangOpts().C11 || getLangOpts().C99) &&
+ FieldTy->isBooleanType() &&
+ Value.getZExtValue() > 1) {
+ if (FieldName)
+ Diag(FieldLoc, diag::warn_bitfield_width_longer_than_necessary)
+ << FieldName << (unsigned)Value.getZExtValue();
+ else
+ Diag(FieldLoc, diag::warn_anon_bitfield_width_longer_than_necessary)
+ << (unsigned)Value.getZExtValue();
+ }
}
return BitWidth;
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -4317,14 +4317,20 @@
"size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)">;
def err_incorrect_number_of_vector_initializers : Error<
"number of elements must be either one or match the size of the vector">;
+def warn_bitfield_width_longer_than_necessary : Warning<
+ "size of bit-field %0 (%1 bits) exceeds the minimum width required to "
+ "represent all valid values of that bit-field type">, InGroup<BitFieldWidth>;
+def warn_anon_bitfield_width_longer_than_necessary : Warning<
+ "size of anonymous bit-field (%0 bits) exceeds the minimum width required to "
+ "represent all valid values of that bit-field type">, InGroup<BitFieldWidth>;
// 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">;
+ "truncated to %2 bits">, InGroup<BitFieldWidth>;
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">;
+ "be truncated to %1 bits">, InGroup<BitFieldWidth>;
def warn_missing_braces : Warning<
"suggest braces around initialization of subobject">,
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -32,6 +32,7 @@
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">;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits