[cfe-commits] r60628 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Sema/Sema.h lib/Sema/SemaDecl.cpp test/Sema/bitfield.c

Anders Carlsson andersca at mac.com
Sat Dec 6 12:33:04 PST 2008


Author: andersca
Date: Sat Dec  6 14:33:04 2008
New Revision: 60628

URL: http://llvm.org/viewvc/llvm-project?rev=60628&view=rev
Log:
Add diagnostics for bitfields.

Added:
    cfe/trunk/test/Sema/bitfield.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=60628&r1=60627&r2=60628&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sat Dec  6 14:33:04 2008
@@ -1042,6 +1042,10 @@
      "illegal initializer type %0")
 DIAG(err_implicit_empty_initializer, ERROR,
      "initializer for aggregate with no elements requires explicit braces")
+DIAG(err_bitfield_has_negative_width, ERROR,
+     "bit-field %0 has negative width")
+DIAG(err_bitfield_width_exceeds_type_size, ERROR,
+     "size of bit-field %0 exceeds size of its type (%1 bits)")
 
 DIAG(err_redefinition_of_label, ERROR,
      "redefinition of label '%0'")

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=60628&r1=60627&r2=60628&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Dec  6 14:33:04 2008
@@ -1384,8 +1384,14 @@
   /// VerifyIntegerConstantExpression - verifies that an expression is an ICE,
   /// and reports the appropriate diagnostics. Returns false on success.
   /// Can optionally return the value of the expression.
-  bool VerifyIntegerConstantExpression(const Expr*E, llvm::APSInt *Result = 0);
+  bool VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result = 0);
 
+  /// VerifyBitField - verifies that a bit field expression is an ICE and has
+  /// the correct width, and that the field type is valid. 
+  /// Returns false on success.
+  bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, 
+                      QualType FieldTy, const Expr *BitWidth);
+  
   //===--------------------------------------------------------------------===//
   // Extra semantic analysis beyond the C type system
 private:

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=60628&r1=60627&r2=60628&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Dec  6 14:33:04 2008
@@ -2599,6 +2599,31 @@
   return QualType();
 }
 
+bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, 
+                          QualType FieldTy, const Expr *BitWidth)
+{
+  // FIXME: 6.7.2.1p4 - verify the field type.
+  
+  llvm::APSInt Value;
+  if (VerifyIntegerConstantExpression(BitWidth, &Value))
+    return true;
+
+  if (Value.isNegative()) {
+    Diag(FieldLoc, diag::err_bitfield_has_negative_width) << FieldName;
+    return true;
+  }
+
+  uint64_t TypeSize = Context.getTypeSize(FieldTy);
+  // FIXME: We won't need the 0 size once we check that the field type is valid.
+  if (TypeSize && Value.getZExtValue() > TypeSize) {
+    Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) << 
+         FieldName << (unsigned)TypeSize;
+    return true;
+  }
+
+  return false;
+}
+
 /// ActOnField - Each field of a struct/union/class is passed into this in order
 /// to create a FieldDecl object for it.
 Sema::DeclTy *Sema::ActOnField(Scope *S,
@@ -2611,25 +2636,11 @@
   
   // FIXME: Unnamed fields can be handled in various different ways, for
   // example, unnamed unions inject all members into the struct namespace!
-    
-  if (BitWidth) {
-    // TODO: Validate.
-    //printf("WARNING: BITFIELDS IGNORED!\n");
-    
-    // 6.7.2.1p3
-    // 6.7.2.1p4
-    
-  } else {
-    // Not a bitfield.
 
-    // validate II.
-    
-  }
-  
   QualType T = GetTypeForDeclarator(D, S);
   assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
   bool InvalidDecl = false;
-
+  
   // C99 6.7.2.1p8: A member of a structure or union may have any type other
   // than a variably modified type.
   if (T->isVariablyModifiedType()) {
@@ -2643,6 +2654,17 @@
       InvalidDecl = true;
     }
   }
+  
+  if (BitWidth) {
+    if (VerifyBitField(Loc, II, T, BitWidth))
+      InvalidDecl = true;
+  } else {
+    // Not a bitfield.
+
+    // validate II.
+    
+  }
+  
   // FIXME: Chain fielddecls together.
   FieldDecl *NewFD;
 
@@ -2692,6 +2714,9 @@
   // FIXME: Unnamed fields can be handled in various different ways, for
   // example, unnamed unions inject all members into the struct namespace!
   
+  QualType T = GetTypeForDeclarator(D, S);
+  assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
+  bool InvalidDecl = false;
   
   if (BitWidth) {
     // TODO: Validate.
@@ -2707,10 +2732,6 @@
     
   }
   
-  QualType T = GetTypeForDeclarator(D, S);
-  assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
-  bool InvalidDecl = false;
-  
   // C99 6.7.2.1p8: A member of a structure or union may have any type other
   // than a variably modified type.
   if (T->isVariablyModifiedType()) {

Added: cfe/trunk/test/Sema/bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/bitfield.c?rev=60628&view=auto

==============================================================================
--- cfe/trunk/test/Sema/bitfield.c (added)
+++ cfe/trunk/test/Sema/bitfield.c Sat Dec  6 14:33:04 2008
@@ -0,0 +1,8 @@
+// RUN: clang %s -fsyntax-only -verify 
+
+struct a {
+  int a : -1; // expected-error{{bit-field 'a' has negative width}}
+  int b : 33; // expected-error{{size of bit-field 'b' exceeds size 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); 
+};





More information about the cfe-commits mailing list