[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