From d25db7ed0f8ec288a770a75b88caaa688ac22079 Mon Sep 17 00:00:00 2001 From: John McCall Date: Mon, 6 May 2013 21:39:12 +0000 Subject: Grab-bag of bit-field fixes: - References to ObjC bit-field ivars are bit-field lvalues; fixes rdar://13794269, which got me started down this. - Introduce Expr::refersToBitField, switch a couple users to it where semantically important, and comment the difference between this and the existing API. - Discourage Expr::getBitField by making it a bit longer and less general-sounding. - Lock down on const_casts of bit-field gl-values until we hear back from the committee as to whether they're allowed. llvm-svn: 181252 --- clang/lib/Sema/SemaCast.cpp | 12 +++++++++++- clang/lib/Sema/SemaChecking.cpp | 4 ++-- clang/lib/Sema/SemaExpr.cpp | 2 +- clang/lib/Sema/SemaInit.cpp | 15 ++++++++++----- clang/lib/Sema/SemaOverload.cpp | 2 +- 5 files changed, 25 insertions(+), 10 deletions(-) (limited to 'clang/lib/Sema') diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index d6c378e3d48..eb11a577cb0 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1452,7 +1452,7 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType, DestType = Self.Context.getCanonicalType(DestType); QualType SrcType = SrcExpr->getType(); if (const ReferenceType *DestTypeTmp =DestType->getAs()) { - if (DestTypeTmp->isLValueReferenceType() && !SrcExpr->isLValue()) { + if (isa(DestTypeTmp) && !SrcExpr->isLValue()) { // Cannot const_cast non-lvalue to lvalue reference type. But if this // is C-style, static_cast might find a way, so we simply suggest a // message and tell the parent to keep searching. @@ -1460,6 +1460,16 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType, return TC_NotApplicable; } + // It's not completely clear under the standard whether we can + // const_cast bit-field gl-values. Doing so would not be + // intrinsically complicated, but for now, we say no for + // consistency with other compilers and await the word of the + // committee. + if (SrcExpr->refersToBitField()) { + msg = diag::err_bad_cxx_cast_bitfield; + return TC_NotApplicable; + } + // C++ 5.2.11p4: An lvalue of type T1 can be [cast] to an lvalue of type T2 // [...] if a pointer to T1 can be [cast] to the type pointer to T2. DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType()); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e14635ee25d..a0998a46c66 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4311,7 +4311,7 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { IntRange::forValueOfType(C, E->getType()); } - if (FieldDecl *BitField = E->getBitField()) + if (FieldDecl *BitField = E->getSourceBitField()) return IntRange(BitField->getBitWidthValue(C), BitField->getType()->isUnsignedIntegerOrEnumerationType()); @@ -4688,7 +4688,7 @@ static void AnalyzeAssignment(Sema &S, BinaryOperator *E) { // We want to recurse on the RHS as normal unless we're assigning to // a bitfield. - if (FieldDecl *Bitfield = E->getLHS()->getBitField()) { + if (FieldDecl *Bitfield = E->getLHS()->getSourceBitField()) { if (AnalyzeBitFieldAssignment(S, Bitfield, E->getRHS(), E->getOperatorLoc())) { // Recurse, ignoring any implicit conversions on the RHS. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0c1065813eb..dd05b822364 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3383,7 +3383,7 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, isInvalid = CheckAlignOfExpr(*this, E); } else if (ExprKind == UETT_VecStep) { isInvalid = CheckVecStepExpr(E); - } else if (E->getBitField()) { // C99 6.5.3.4p1. + } else if (E->refersToBitField()) { // C99 6.5.3.4p1. Diag(E->getExprLoc(), diag::err_sizeof_alignof_bitfield) << 0; isInvalid = true; } else { diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index de93adb6be1..9e8936e17b8 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3440,7 +3440,7 @@ convertQualifiersAndValueKindIfNecessary(Sema &S, Qualifiers T1Quals, Qualifiers T2Quals, bool IsLValueRef) { - bool IsNonAddressableType = Initializer->getBitField() || + bool IsNonAddressableType = Initializer->refersToBitField() || Initializer->refersToVectorElement(); if (IsNonAddressableType) { @@ -5225,13 +5225,18 @@ InitializationSequence::Perform(Sema &S, } case SK_BindReference: - if (FieldDecl *BitField = CurInit.get()->getBitField()) { - // References cannot bind to bit fields (C++ [dcl.init.ref]p5). + // References cannot bind to bit-fields (C++ [dcl.init.ref]p5). + if (CurInit.get()->refersToBitField()) { + // We don't necessarily have an unambiguous source bit-field. + FieldDecl *BitField = CurInit.get()->getSourceBitField(); S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield) << Entity.getType().isVolatileQualified() - << BitField->getDeclName() + << (BitField ? BitField->getDeclName() : DeclarationName()) + << (BitField != NULL) << CurInit.get()->getSourceRange(); - S.Diag(BitField->getLocation(), diag::note_bitfield_decl); + if (BitField) + S.Diag(BitField->getLocation(), diag::note_bitfield_decl); + return ExprError(); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c11a0756e70..529ba127cba 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1837,7 +1837,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { // conversion. using llvm::APSInt; if (From) - if (FieldDecl *MemberDecl = From->getBitField()) { + if (FieldDecl *MemberDecl = From->getSourceBitField()) { APSInt BitWidth; if (FromType->isIntegralType(Context) && MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) { -- cgit v1.2.3