]> granicus.if.org Git - clang/commitdiff
Start working on handling wide bitfields in C++
authorAnders Carlsson <andersca@mac.com>
Fri, 16 Apr 2010 15:16:32 +0000 (15:16 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 16 Apr 2010 15:16:32 +0000 (15:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101464 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/SemaCXX/bitfield-layout.cpp [new file with mode: 0644]

index 6f430ff7d3664074885631ba896402d9e90d4e5f..85ca9e9fbb497ad60217342b844847b3000fb641 100644 (file)
@@ -1669,6 +1669,15 @@ 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)">;
+  
+// 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_missing_braces : Warning<
   "suggest braces around initialization of subobject">,
   InGroup<DiagGroup<"missing-braces">>, DefaultIgnore;
index 2e8deacf36b142c52f234b01a51cacaf4468640e..182a85aee80f636303de73740ab0272c60aa1738 100644 (file)
@@ -5375,11 +5375,23 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
   if (!FieldTy->isDependentType()) {
     uint64_t TypeSize = Context.getTypeSize(FieldTy);
     if (Value.getZExtValue() > TypeSize) {
+      if (!getLangOptions().CPlusPlus) {
+        if (FieldName) 
+          return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size)
+            << FieldName << (unsigned)Value.getZExtValue() 
+            << (unsigned)TypeSize;
+        
+        return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_size)
+          << (unsigned)Value.getZExtValue() << (unsigned)TypeSize;
+      }
+      
       if (FieldName)
-        return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size)
-          << FieldName << (unsigned)Value.getZExtValue() << (unsigned)TypeSize;
-      return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_size)
-        << (unsigned)Value.getZExtValue() << (unsigned)TypeSize;
+        Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_size)
+          << FieldName << (unsigned)Value.getZExtValue() 
+          << (unsigned)TypeSize;
+      else
+        Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_size)
+          << (unsigned)Value.getZExtValue() << (unsigned)TypeSize;        
     }
   }
 
diff --git a/test/SemaCXX/bitfield-layout.cpp b/test/SemaCXX/bitfield-layout.cpp
new file mode 100644 (file)
index 0000000..318a57f
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-apple-darwin10
+
+#define CHECK_SIZE(name, size) extern int name##1[sizeof(name) == size ? 1 : -1];
+#define CHECK_ALIGN(name, size) extern int name##2[__alignof(name) == size ? 1 : -1];
+
+// Simple test.
+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}}
+};
+CHECK_SIZE(Test1, 2);
+CHECK_ALIGN(Test1, 1);
+