[cfe-commits] r70623 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/Expr.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp test/Sema/bitfield.c

Douglas Gregor dgregor at apple.com
Fri May 1 19:18:30 PDT 2009


Author: dgregor
Date: Fri May  1 21:18:30 2009
New Revision: 70623

URL: http://llvm.org/viewvc/llvm-project?rev=70623&view=rev
Log:
When determining whether an expression refers to a bit-field, look
into the left-hand side of an assignment expression. This completes
most of PR3500; the only remaining part is to deal with the
GCC-specific implementation-defined behavior for "unsigned long" (and
other) bit-fields.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/Sema/bitfield.c

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=70623&r1=70622&r2=70623&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri May  1 21:18:30 2009
@@ -175,7 +175,9 @@
   isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
                                               SourceLocation *Loc = 0) const;
   
-  bool isBitField();
+  /// \brief If this expression refers to a bit-field, retrieve the
+  /// declaration of that bit-field.
+  FieldDecl *getBitField();
 
   /// isIntegerConstantExpr - Return true if this expression is a valid integer
   /// constant expression, and, if so, return its value in Result.  If not a

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=70623&r1=70622&r2=70623&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri May  1 21:18:30 2009
@@ -1379,13 +1379,19 @@
   return isIntegerConstantExpr(Result, Ctx) && Result == 0;
 }
 
-/// isBitField - Return true if this expression is a bit-field.
-bool Expr::isBitField() {
+FieldDecl *Expr::getBitField() {
   Expr *E = this->IgnoreParenCasts();
+
   if (MemberExpr *MemRef = dyn_cast<MemberExpr>(E))
     if (FieldDecl *Field = dyn_cast<FieldDecl>(MemRef->getMemberDecl()))
-        return Field->isBitField();
-  return false;
+      if (Field->isBitField())
+        return Field;
+
+  if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E))
+    if (BinOp->isAssignmentOp() && BinOp->getLHS())
+      return BinOp->getLHS()->getBitField();
+
+  return 0;
 }
 
 /// isArrow - Return true if the base expression is a pointer to vector,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri May  1 21:18:30 2009
@@ -2090,7 +2090,7 @@
   //
   // Note that the bit-field check is skipped if we are just computing
   // the implicit conversion sequence (C++ [over.best.ics]p2).
-  if (InitLvalue == Expr::LV_Valid && (ICS || !Init->isBitField()) &&
+  if (InitLvalue == Expr::LV_Valid && (ICS || !Init->getBitField()) &&
       RefRelationship >= Ref_Compatible_With_Added_Qualification) {
     BindsDirectly = true;
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri May  1 21:18:30 2009
@@ -128,12 +128,8 @@
 /// \returns the type this bit-field will promote to, or NULL if no
 /// promotion occurs.
 static QualType isPromotableBitField(Expr *E, ASTContext &Context) {
-  MemberExpr *MemRef = dyn_cast<MemberExpr>(E->IgnoreParenCasts());
-  if (!MemRef)
-    return QualType();
-
-  FieldDecl *Field = dyn_cast<FieldDecl>(MemRef->getMemberDecl());
-  if (!Field || !Field->isBitField())
+  FieldDecl *Field = E->getBitField();
+  if (!Field)
     return QualType();
 
   const BuiltinType *BT = Field->getType()->getAsBuiltinType();
@@ -1344,16 +1340,17 @@
   if (E->isTypeDependent())
     return false;
 
-  if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
-    if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
-      if (FD->isBitField()) {
-        Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 1 << ExprRange;
-        return true;
-      }
-      // Other fields are ok.
-      return false;
-    }
+  if (E->getBitField()) {
+    Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 1 << ExprRange;
+    return true;
   }
+
+  // Alignment of a field access is always okay, so long as it isn't a
+  // bit-field.
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    if (dyn_cast<FieldDecl>(ME->getMemberDecl()))
+      return false;
+
   return CheckSizeOfAlignOfOperand(E->getType(), OpLoc, ExprRange, false);
 }
 
@@ -1385,7 +1382,7 @@
     // Delay type-checking for type-dependent expressions.
   } else if (!isSizeOf) {
     isInvalid = CheckAlignOfExpr(E, OpLoc, R);
-  } else if (E->isBitField()) {  // C99 6.5.3.4p1.
+  } else if (E->getBitField()) {  // C99 6.5.3.4p1.
     Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 0;
     isInvalid = true;
   } else {
@@ -4254,7 +4251,7 @@
         << op->getSourceRange();
       return QualType();
     }
-  } else if (op->isBitField()) { // C99 6.5.3.2p1
+  } else if (op->getBitField()) { // C99 6.5.3.2p1
     // The operand cannot be a bit-field
     Diag(OpLoc, diag::err_typecheck_address_of)
       << "bit-field" << op->getSourceRange();

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri May  1 21:18:30 2009
@@ -746,14 +746,14 @@
   // other value of that type for promotion purposes (C++ 4.5p3).
   // FIXME: We should delay checking of bit-fields until we actually
   // perform the conversion.
-  if (MemberExpr *MemRef = dyn_cast_or_null<MemberExpr>(From)) {
-    using llvm::APSInt;
-    if (FieldDecl *MemberDecl = dyn_cast<FieldDecl>(MemRef->getMemberDecl())) {
+  using llvm::APSInt;
+  if (From)
+    if (FieldDecl *MemberDecl = From->getBitField()) {
       APSInt BitWidth;
-      if (MemberDecl->isBitField() &&
-          FromType->isIntegralType() && !FromType->isEnumeralType() &&
-          From->isIntegerConstantExpr(BitWidth, Context)) {
-        APSInt ToSize(Context.getTypeSize(ToType));
+      if (FromType->isIntegralType() && !FromType->isEnumeralType() &&
+          MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) {
+        APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned());
+        ToSize = Context.getTypeSize(ToType);
         
         // Are we promoting to an int from a bitfield that fits in an int?
         if (BitWidth < ToSize ||
@@ -770,8 +770,7 @@
         return false;
       }
     }
-  }
-
+  
   // An rvalue of type bool can be converted to an rvalue of type int,
   // with false becoming zero and true becoming one (C++ 4.5p4).
   if (FromType->isBooleanType() && To->getKind() == BuiltinType::Int) {

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

==============================================================================
--- cfe/trunk/test/Sema/bitfield.c (original)
+++ cfe/trunk/test/Sema/bitfield.c Fri May  1 21:18:30 2009
@@ -31,6 +31,6 @@
 int y;
 
 struct {unsigned x : 2;} x2;
-// FIXME: __typeof__((x.x+=1)+1) y;
+__typeof__((x.x+=1)+1) y;
 __typeof__(x.x<<1) y;
 int y;





More information about the cfe-commits mailing list