forked from OSchip/llvm-project
Introduce a new cast kind for an "lvalue bitcast", which handles
reinterpret_casts (possibly indirectly via C-style/functional casts) on values, e.g., int i; reinterpret_cast<short&>(i); The IR generated for this is essentially the same as for *reinterpret_cast<short*>(&i). Fixes PR6437, PR7593, and PR7344. llvm-svn: 108294
This commit is contained in:
parent
11e8f3ba37
commit
51954276cc
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Reference in New Issue