[cfe-commits] r66210 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/Sema/bitfield.c test/SemaCXX/class.cpp

Chris Lattner sabre at nondot.org
Thu Mar 5 14:45:59 PST 2009


Author: lattner
Date: Thu Mar  5 16:45:59 2009
New Revision: 66210

URL: http://llvm.org/viewvc/llvm-project?rev=66210&view=rev
Log:
fix PR3607 and a fixme, by checking bitfield constraints
more consistently.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/Sema/bitfield.c
    cfe/trunk/test/SemaCXX/class.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Thu Mar  5 16:45:59 2009
@@ -249,7 +249,7 @@
 DIAG(err_static_not_bitfield, ERROR,
      "static member %0 cannot be a bit-field")
 DIAG(err_not_integral_type_bitfield, ERROR,
-     "bit-field %0 with non-integral type")
+     "bit-field %0 has non-integral type")
 DIAG(err_member_initialization, ERROR,
     "%0 can only be initialized if it is a static const integral data member")
 DIAG(err_member_function_initialization, ERROR,

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Mar  5 16:45:59 2009
@@ -361,6 +361,10 @@
                          llvm::SmallVectorImpl<DeclTy*> &Decls);
   virtual DeclTy *ActOnField(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
                              Declarator &D, ExprTy *BitfieldWidth);
+
+  FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
+                         Declarator &D, Expr *BitfieldWidth);
+
   
   virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart,
                             Declarator &D, ExprTy *BitfieldWidth,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Mar  5 16:45:59 2009
@@ -2575,7 +2575,8 @@
       }
     }
     if (isa<DeclStmt>(*i)) continue;
-    RecursiveCalcJumpScopes(LabelScopeMap, PopScopeMap, GotoScopeMap, ScopeStack, *i);
+    RecursiveCalcJumpScopes(LabelScopeMap, PopScopeMap, GotoScopeMap,
+                            ScopeStack, *i);
   }
 
   while (ScopeStack.size() && PopScopeMap[ScopeStack.back()] == CurStmt) {
@@ -3150,7 +3151,14 @@
 
 bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, 
                           QualType FieldTy, const Expr *BitWidth) {
-  // FIXME: 6.7.2.1p4 - verify the field type.
+  // C99 6.7.2.1p4 - verify the field type.
+
+  if (!FieldTy->isIntegralType()) {
+    // Handle incomplete types with specific error.
+    if (FieldTy->isIncompleteType())
+      return Diag(FieldLoc, diag::err_field_incomplete) << FieldTy;
+    return Diag(FieldLoc, diag::err_not_integral_type_bitfield) << FieldName;
+  }
   
   llvm::APSInt Value;
   if (VerifyIntegerConstantExpression(BitWidth, &Value))
@@ -3177,15 +3185,19 @@
 Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
                                SourceLocation DeclStart, 
                                Declarator &D, ExprTy *BitfieldWidth) {
+  return HandleField(S, static_cast<RecordDecl*>(TagD), DeclStart, D,
+                     static_cast<Expr*>(BitfieldWidth));
+}
+
+/// HandleField - Analyze a field of a C struct or a C++ data member.
+///
+FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
+                             SourceLocation DeclStart,
+                             Declarator &D, Expr *BitWidth) {
   IdentifierInfo *II = D.getIdentifier();
-  Expr *BitWidth = (Expr*)BitfieldWidth;
   SourceLocation Loc = DeclStart;
-  RecordDecl *Record = (RecordDecl *)TagD;
   if (II) Loc = D.getIdentifierLoc();
   
-  // 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;
@@ -3210,8 +3222,11 @@
   }
   
   if (BitWidth) {
-    if (VerifyBitField(Loc, II, T, BitWidth))
+    if (VerifyBitField(Loc, II, T, BitWidth)) {
       InvalidDecl = true;
+      DeleteExpr(BitWidth);
+      BitWidth = 0;
+    }
   } else {
     // Not a bitfield.
 
@@ -3290,8 +3305,11 @@
   
   if (BitWidth) {
     // 6.7.2.1p3, 6.7.2.1p4
-    if (VerifyBitField(Loc, II, T, BitWidth))
+    if (VerifyBitField(Loc, II, T, BitWidth)) {
       InvalidDecl = true;
+      DeleteExpr(BitWidth);
+      BitWidth = 0;
+    }
   } else {
     // Not a bitfield.
     
@@ -3373,6 +3391,11 @@
       // Remember all fields written by the user.
       RecFields.push_back(FD);
     }
+    
+    // If the field is already invalid for some reason, don't emit more
+    // diagnostics about it.
+    if (FD->isInvalidDecl())
+      continue;
       
     // C99 6.7.2.1p2 - A field may not be a function type.
     if (FDTy->isFunctionType()) {
@@ -3466,7 +3489,8 @@
              IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
           ObjCIvarDecl* Ivar = (*IVI);
           IdentifierInfo *II = Ivar->getIdentifier();
-          ObjCIvarDecl* prevIvar = ID->getSuperClass()->lookupInstanceVariable(II);
+          ObjCIvarDecl* prevIvar =
+            ID->getSuperClass()->lookupInstanceVariable(II);
           if (prevIvar) {
             Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
             Diag(prevIvar->getLocation(), diag::note_previous_declaration);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Mar  5 16:45:59 2009
@@ -547,11 +547,15 @@
   Decl *Member;
   bool InvalidDecl = false;
 
-  if (isInstField)
-    Member = static_cast<Decl*>(ActOnField(S, cast<CXXRecordDecl>(CurContext), 
-                                           Loc, D, BitWidth));
-  else
+  if (isInstField) {
+    FieldDecl *FD = 
+      HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth);
+    // Refresh our notion of bitwidth.
+    BitWidth = FD->getBitWidth();
+    Member = FD;
+  } else {
     Member = static_cast<Decl*>(ActOnDeclarator(S, D, LastInGroup));
+  }
 
   if (!Member) return LastInGroup;
 

Modified: cfe/trunk/test/Sema/bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/bitfield.c?rev=66210&r1=66209&r2=66210&view=diff

==============================================================================
--- cfe/trunk/test/Sema/bitfield.c (original)
+++ cfe/trunk/test/Sema/bitfield.c Thu Mar  5 16:45:59 2009
@@ -1,4 +1,5 @@
 // RUN: clang %s -fsyntax-only -verify 
+enum e0;
 
 struct a {
   int a : -1; // expected-error{{bit-field 'a' has negative width}}
@@ -11,4 +12,10 @@
 
   // rdar://6138816
   int e : 0;  // expected-error {{bit-field 'e' has zero width}}
+
+  float xx : 4;  // expected-error {{bit-field 'xx' has non-integral type}}
+
+  // PR3607
+  enum e0 f : 1; // expected-error {{field has incomplete type 'enum e0'}}
 };
+

Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=66210&r1=66209&r2=66210&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Thu Mar  5 16:45:59 2009
@@ -27,8 +27,8 @@
   typedef int func();
   func tm;
   func *ptm;
-  func btm : 1; // expected-error {{error: bit-field 'btm' with non-integral type}}
-  NestedC bc : 1; // expected-error {{error: bit-field 'bc' with non-integral type}}
+  func btm : 1; // expected-error {{error: bit-field 'btm' has non-integral type}}
+  NestedC bc : 1; // expected-error {{error: bit-field 'bc' has non-integral type}}
 
   enum E1 { en1, en2 };
 





More information about the cfe-commits mailing list