diff options
-rw-r--r-- | clang/include/clang/AST/Expr.h | 5 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Checker/GRExprEngine.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCXXCast.cpp | 7 |
8 files changed, 29 insertions, 3 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 807644349e5..ade2b09c80c 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1854,6 +1854,10 @@ public: /// CK_BitCast - Used for reinterpret_cast. CK_BitCast, + /// CK_LValueBitCast - Used for reinterpret_cast of expressions to + /// a reference type. + CK_LValueBitCast, + /// CK_NoOp - Used for const_cast. CK_NoOp, @@ -1957,6 +1961,7 @@ private: // These should not have an inheritance path. case CK_Unknown: case CK_BitCast: + case CK_LValueBitCast: case CK_NoOp: case CK_Dynamic: case CK_ToUnion: diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index bd97b886fe1..6524a312dc8 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -684,6 +684,8 @@ const char *CastExpr::getCastKindName() const { return "Unknown"; case CastExpr::CK_BitCast: return "BitCast"; + case CastExpr::CK_LValueBitCast: + return "LValueBitCast"; case CastExpr::CK_NoOp: return "NoOp"; case CastExpr::CK_BaseToDerived: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index a963182ae88..3c974203326 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -563,6 +563,7 @@ bool PointerExprEvaluator::VisitCastExpr(CastExpr* E) { case CastExpr::CK_NoOp: case CastExpr::CK_BitCast: + case CastExpr::CK_LValueBitCast: case CastExpr::CK_AnyPointerToObjCPointerCast: case CastExpr::CK_AnyPointerToBlockPointerCast: return Visit(SubExpr); diff --git a/clang/lib/Checker/GRExprEngine.cpp b/clang/lib/Checker/GRExprEngine.cpp index 4652a4c89ff..07fee9d39e4 100644 --- a/clang/lib/Checker/GRExprEngine.cpp +++ b/clang/lib/Checker/GRExprEngine.cpp @@ -2438,6 +2438,7 @@ void GRExprEngine::VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred, case CastExpr::CK_Unknown: case CastExpr::CK_ArrayToPointerDecay: case CastExpr::CK_BitCast: + case CastExpr::CK_LValueBitCast: case CastExpr::CK_IntegralCast: case CastExpr::CK_IntegralToPointer: case CastExpr::CK_PointerToIntegral: diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 0426a60f0c3..5a4808bce9d 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1816,7 +1816,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { return LValue::MakeAddr(Derived, MakeQualifiers(E->getType())); } - case CastExpr::CK_BitCast: { + case CastExpr::CK_BitCast: + case CastExpr::CK_LValueBitCast: { // This must be a reinterpret_cast (or c-style equivalent). const ExplicitCastExpr *CE = cast<ExplicitCastExpr>(E); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 20722f7799c..219a5f91532 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -307,6 +307,10 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { break; } + case CastExpr::CK_LValueBitCast: + llvm_unreachable("there are no lvalue bit-casts on aggregates"); + break; + case CastExpr::CK_BitCast: { // This must be a member function pointer cast. Visit(E->getSubExpr()); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 1ebc2c571a0..ef38209e1ea 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -925,6 +925,15 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { //assert(0 && "Unknown cast kind!"); break; + case CastExpr::CK_LValueBitCast: { + Value *V = EmitLValue(E).getAddress(); + V = Builder.CreateBitCast(V, + ConvertType(CGF.getContext().getPointerType(DestTy))); + // FIXME: Are the qualifiers correct here? + return EmitLoadOfLValue(LValue::MakeAddr(V, CGF.MakeQualifiers(DestTy)), + DestTy); + } + case CastExpr::CK_AnyPointerToObjCPointerCast: case CastExpr::CK_AnyPointerToBlockPointerCast: case CastExpr::CK_BitCast: { diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index 911578622d2..b8e27e7b728 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -1052,6 +1052,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind) { + bool IsLValueCast = false; + DestType = Self.Context.getCanonicalType(DestType); QualType SrcType = SrcExpr->getType(); if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) { @@ -1069,6 +1071,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, // This code does this transformation for the checked types. DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType()); SrcType = Self.Context.getPointerType(SrcType); + IsLValueCast = true; } // Canonicalize source for comparison. @@ -1095,7 +1098,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, } // A valid member pointer cast. - Kind = CastExpr::CK_BitCast; + Kind = IsLValueCast? CastExpr::CK_LValueBitCast : CastExpr::CK_BitCast; return TC_Success; } @@ -1212,7 +1215,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, // Not casting away constness, so the only remaining check is for compatible // pointer categories. - Kind = CastExpr::CK_BitCast; + Kind = IsLValueCast? CastExpr::CK_LValueBitCast : CastExpr::CK_BitCast; if (SrcType->isFunctionPointerType()) { if (DestType->isFunctionPointerType()) { |