forked from OSchip/llvm-project
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. llvm-svn: 70623
This commit is contained in:
parent
49805454e6
commit
71235ecb7f
|
@ -175,7 +175,9 @@ public:
|
|||
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
|
||||
|
|
|
@ -1379,13 +1379,19 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx) const
|
|||
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,
|
||||
|
|
|
@ -2090,7 +2090,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
|
|||
//
|
||||
// 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;
|
||||
|
||||
|
|
|
@ -128,12 +128,8 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
|
|||
/// \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 @@ bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
|
|||
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 @@ Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
|
|||
// 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 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
|
|||
<< 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();
|
||||
|
|
|
@ -746,14 +746,14 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
|
|||
// 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 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
|
|||
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) {
|
||||
|
|
|
@ -31,6 +31,6 @@ __typeof__(x.x+1) y;
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue