]> granicus.if.org Git - clang/commitdiff
MS wide bitfield error check in Sema
authorReid Kleckner <reid@kleckner.net>
Wed, 17 Jul 2013 20:46:03 +0000 (20:46 +0000)
committerReid Kleckner <reid@kleckner.net>
Wed, 17 Jul 2013 20:46:03 +0000 (20:46 +0000)
cl.exe treats wide bitfields as an error. This patch causes them to be
an error if IsMsStruct is true, as it is in straight C.

Patch by Warren Hunt!

Reviewers: eli.friedman

Differential Revision: http://llvm-reviews.chandlerc.com/D1125

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

include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
test/SemaCXX/ms_wide_bitfield.cpp [new file with mode: 0644]

index 495ba48d7498c1d60069d7353ad67993854d34fb..835151aa983b4921b6165bd3caada10574c895ba 100644 (file)
@@ -7286,8 +7286,8 @@ public:
   /// Returns false on success.
   /// Can optionally return whether the bit-field is of width 0
   ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
-                            QualType FieldTy, Expr *BitWidth,
-                            bool *ZeroWidth = 0);
+                            QualType FieldTy, bool IsMsStruct,
+                            Expr *BitWidth, bool *ZeroWidth = 0);
 
   enum CUDAFunctionTarget {
     CFT_Device,
index e0dab1c4f1ce68297b4b0719b6abbfec57bb27b1..b860823ff62434eb8a646ae966a259ed51e92c61 100644 (file)
@@ -10575,8 +10575,8 @@ void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
 // Note that FieldName may be null for anonymous bitfields.
 ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
                                 IdentifierInfo *FieldName,
-                                QualType FieldTy, Expr *BitWidth,
-                                bool *ZeroWidth) {
+                                QualType FieldTy, bool IsMsStruct,
+                                Expr *BitWidth, bool *ZeroWidth) {
   // Default to true; that shouldn't confuse checks for emptiness
   if (ZeroWidth)
     *ZeroWidth = true;
@@ -10625,7 +10625,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
   if (!FieldTy->isDependentType()) {
     uint64_t TypeSize = Context.getTypeSize(FieldTy);
     if (Value.getZExtValue() > TypeSize) {
-      if (!getLangOpts().CPlusPlus) {
+      if (!getLangOpts().CPlusPlus || IsMsStruct) {
         if (FieldName) 
           return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size)
             << FieldName << (unsigned)Value.getZExtValue() 
@@ -10843,7 +10843,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
   bool ZeroWidth = false;
   // If this is declared as a bit-field, check the bit-field.
   if (!InvalidDecl && BitWidth) {
-    BitWidth = VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth).take();
+    BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth,
+                              &ZeroWidth).take();
     if (!BitWidth) {
       InvalidDecl = true;
       BitWidth = 0;
@@ -11024,7 +11025,8 @@ Decl *Sema::ActOnIvar(Scope *S,
 
   if (BitWidth) {
     // 6.7.2.1p3, 6.7.2.1p4
-    BitWidth = VerifyBitField(Loc, II, T, BitWidth).take();
+    BitWidth =
+        VerifyBitField(Loc, II, T, /*IsMsStruct=*/false, BitWidth).take();
     if (!BitWidth)
       D.setInvalidType();
   } else {
diff --git a/test/SemaCXX/ms_wide_bitfield.cpp b/test/SemaCXX/ms_wide_bitfield.cpp
new file mode 100644 (file)
index 0000000..d917390
--- /dev/null
@@ -0,0 +1,9 @@
+// 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)}}
+};
+
+int a[sizeof(A) == 1 ? 1 : -1];