]> granicus.if.org Git - clang/commitdiff
[MS ABI] Restore our warning for overwide bitfields using the MS ABI
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 15 Sep 2015 02:36:41 +0000 (02:36 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 15 Sep 2015 02:36:41 +0000 (02:36 +0000)
This restores a diagnostic lost in r247651.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@247659 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/SemaCXX/ms_wide_bitfield.cpp

index 9c641ddbb65d93fb9e6824607e0fb8123182e89f..2ed4a61aaba4e0c6f61dde117ac84876e9b08e1a 100644 (file)
@@ -12626,29 +12626,36 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
   }
 
   if (!FieldTy->isDependentType()) {
-    bool UseMSBitfieldSemantics =
-        IsMsStruct || Context.getTargetInfo().getCXXABI().isMicrosoft();
-    bool UseStorageSize = getLangOpts().CPlusPlus && UseMSBitfieldSemantics;
-    uint64_t TypeWidth = UseStorageSize ? Context.getTypeSize(FieldTy)
-                                        : Context.getIntWidth(FieldTy);
-    if (Value.ugt(TypeWidth)) {
-      if (!getLangOpts().CPlusPlus || UseMSBitfieldSemantics) {
-        if (FieldName)
-          return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width)
-            << FieldName << (unsigned)Value.getZExtValue() 
-            << (unsigned)TypeWidth;
-        
-        return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_width)
-          << (unsigned)Value.getZExtValue() << (unsigned)TypeWidth;
-      }
-      
+    uint64_t TypeStorageSize = Context.getTypeSize(FieldTy);
+    uint64_t TypeWidth = Context.getIntWidth(FieldTy);
+    bool BitfieldIsOverwide = Value.ugt(TypeWidth);
+
+    // Over-wide bitfields are an error in C or when using the MSVC bitfield
+    // ABI.
+    bool CStdConstraintViolation =
+        BitfieldIsOverwide && !getLangOpts().CPlusPlus;
+    bool MSBitfieldViolation =
+        Value.ugt(TypeStorageSize) &&
+        (IsMsStruct || Context.getTargetInfo().getCXXABI().isMicrosoft());
+    if (CStdConstraintViolation || MSBitfieldViolation) {
+      unsigned DiagWidth =
+          CStdConstraintViolation ? TypeWidth : TypeStorageSize;
+      if (FieldName)
+        return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width)
+               << FieldName << (unsigned)Value.getZExtValue() << DiagWidth;
+
+      return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_width)
+             << (unsigned)Value.getZExtValue() << DiagWidth;
+    }
+
+    if (BitfieldIsOverwide) {
       if (FieldName)
         Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width)
-          << FieldName << (unsigned)Value.getZExtValue() 
-          << (unsigned)TypeWidth;
+            << FieldName << (unsigned)Value.getZExtValue()
+            << (unsigned)TypeWidth;
       else
         Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_width)
-          << (unsigned)Value.getZExtValue() << (unsigned)TypeWidth;        
+            << (unsigned)Value.getZExtValue() << (unsigned)TypeWidth;
     }
   }
 
index 022d604ec1199f95d4ec8c777429c4407cad6358..3e6a16579c8e7371e9f788be7f39071aba04e100 100644 (file)
@@ -4,7 +4,7 @@ struct A {
   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 (8 bits)}}
-  bool d : 3;
+  bool d : 3; // expected-warning{{width of bit-field 'd' (3 bits) exceeds the width of its type; value will be truncated to 1 bit}}
 };
 
 int a[sizeof(A) == 1 ? 1 : -1];