From 6c7a1f364796ce1acb988714e9e42076d1ce332e Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 24 Sep 2009 22:25:38 +0000 Subject: [PATCH] Patch fixes a code gen. bug in generation of objc_assign_ivar (objc GC's API). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82724 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExpr.cpp | 15 +++++++++++++-- lib/CodeGen/CGObjCGNU.cpp | 6 ++++-- lib/CodeGen/CGObjCMac.cpp | 28 +++++++++++++++++----------- lib/CodeGen/CGObjCRuntime.h | 3 ++- lib/CodeGen/CGValue.h | 5 +++++ 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 309f38e080..332d47c1dd 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -490,8 +490,17 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, // load of a __strong object. llvm::Value *LvalueDst = Dst.getAddress(); llvm::Value *src = Src.getScalarVal(); - if (Dst.isObjCIvar()) - CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, LvalueDst); + if (Dst.isObjCIvar()) { + assert(Dst.getBaseIvarExp() && "BaseIvarExp is NULL"); + const llvm::Type *ResultType = ConvertType(getContext().LongTy); + llvm::Value *RHS = EmitScalarExpr(Dst.getBaseIvarExp()); + RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast"); + llvm::Value *LHS = + Builder.CreatePtrToInt(LvalueDst, ResultType, "sub.ptr.lhs.cast"); + llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset"); + CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, LvalueDst, + BytesBetween); + } else if (Dst.isGlobalObjCRef()) CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst); else @@ -694,6 +703,8 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) { if (isa(E)) { LV.SetObjCIvar(LV, true); + ObjCIvarRefExpr *Exp = cast(const_cast(E)); + LV.setBaseIvarExp(Exp->getBase()); LV.SetObjCArray(LV, E->getType()->isArrayType()); return; } diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index e19debc97f..a08ec472e9 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -170,7 +170,8 @@ public: virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, - llvm::Value *src, llvm::Value *dest); + llvm::Value *src, llvm::Value *dest, + llvm::Value *ivarOffset); virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, @@ -1873,7 +1874,8 @@ void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, } void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, - llvm::Value *src, llvm::Value *dst) { + llvm::Value *src, llvm::Value *dst, + llvm::Value *ivarOffset) { return; } diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index b9f4f3471c..bc4e7f9378 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -369,9 +369,10 @@ public: /// GcAssignIvarFn -- LLVM objc_assign_ivar function. llvm::Constant *getGcAssignIvarFn() { - // id objc_assign_ivar(id, id *) + // id objc_assign_ivar(id, id *, ptrdiff_t) std::vector Args(1, ObjectPtrTy); Args.push_back(ObjectPtrTy->getPointerTo()); + Args.push_back(LongTy); llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, Args, false); return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar"); @@ -1130,7 +1131,8 @@ public: virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, - llvm::Value *src, llvm::Value *dest); + llvm::Value *src, llvm::Value *dest, + llvm::Value *ivarOffset); virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, @@ -1360,7 +1362,8 @@ public: virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, - llvm::Value *src, llvm::Value *dest); + llvm::Value *src, llvm::Value *dest, + llvm::Value *ivarOffset); virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, @@ -2745,10 +2748,12 @@ void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, } /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. -/// objc_assign_ivar (id src, id *dst) +/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset) /// void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, - llvm::Value *src, llvm::Value *dst) { + llvm::Value *src, llvm::Value *dst, + llvm::Value *ivarOffset) { + assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL"); const llvm::Type * SrcTy = src->getType(); if (!isa(SrcTy)) { unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); @@ -2759,8 +2764,8 @@ void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); - CGF.Builder.CreateCall2(ObjCTypes.getGcAssignIvarFn(), - src, dst, "assignivar"); + CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), + src, dst, ivarOffset); return; } @@ -5268,11 +5273,12 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder, return Builder.CreateLoad(Entry, false, "tmp"); } /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. -/// objc_assign_ivar (id src, id *dst) +/// objc_assign_ivar (id src, id *dst, ptrdiff_t) /// void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, - llvm::Value *dst) { + llvm::Value *dst, + llvm::Value *ivarOffset) { const llvm::Type * SrcTy = src->getType(); if (!isa(SrcTy)) { unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); @@ -5283,8 +5289,8 @@ void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, } src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); - CGF.Builder.CreateCall2(ObjCTypes.getGcAssignIvarFn(), - src, dst, "assignivar"); + CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), + src, dst, ivarOffset); return; } diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index a903ac3946..6b45562397 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -189,7 +189,8 @@ public: virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest) = 0; virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, - llvm::Value *src, llvm::Value *dest) = 0; + llvm::Value *src, llvm::Value *dest, + llvm::Value *ivarOffset) = 0; virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest) = 0; diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index ee9dc524c6..2a06f51f66 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -156,6 +156,7 @@ class LValue { // Lvalue is a global reference of an objective-c object bool GlobalObjCRef : 1; + Expr *BaseIvarExp; private: void SetQualifiers(Qualifiers Quals) { this->Quals = Quals; @@ -163,6 +164,7 @@ private: // FIXME: Convenient place to set objc flags to 0. This should really be // done in a user-defined constructor instead. this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; + this->BaseIvarExp = 0; } public: @@ -185,6 +187,9 @@ public: bool isGlobalObjCRef() const { return GlobalObjCRef; } bool isObjCWeak() const { return Quals.getObjCGCAttr() == Qualifiers::Weak; } bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; } + + Expr *getBaseIvarExp() const { return BaseIvarExp; } + void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } unsigned getAddressSpace() const { return Quals.getAddressSpace(); } -- 2.40.0