From e0d987626cc11317b36d6d3cc148c9a9d4b35850 Mon Sep 17 00:00:00 2001 From: David Chisnall <csdavec@swan.ac.uk> Date: Wed, 3 Nov 2010 16:12:44 +0000 Subject: [PATCH] Some fixes for synthesized ivar metadata (GNU runtime). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118172 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjCGNU.cpp | 31 +++++++++++++++++++------------ lib/CodeGen/CGObjCMac.cpp | 1 + 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index eb45d5bcf3..dff4eb7e75 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -1469,7 +1469,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset)); IvarOffsetValues.push_back(new llvm::GlobalVariable(TheModule, IntTy, false, llvm::GlobalValue::ExternalLinkage, - llvm::ConstantInt::get(IntTy, BaseOffset), + llvm::ConstantInt::get(IntTy, Offset), "__objc_ivar_offset_value_" + ClassName +"." + IVD->getNameAsString())); } @@ -1538,7 +1538,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { // allows code compiled for the non-Fragile ABI to inherit from code compiled // for the legacy ABI, without causing problems. The converse is also // possible, but causes all ivar accesses to be fragile. - int i = 0; + // Offset pointer for getting at the correct field in the ivar list when // setting up the alias. These are: The base address for the global, the // ivar array (second field), the ivar in this list (set for each ivar), and @@ -1548,15 +1548,16 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { llvm::ConstantInt::get(IndexTy, 1), 0, llvm::ConstantInt::get(IndexTy, 2) }; - for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(), - endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) { + + for (unsigned i = 0, e = OIvars.size(); i != e; ++i) { + ObjCIvarDecl *IVD = OIvars[i]; const std::string Name = "__objc_ivar_offset_" + ClassName + '.' - +(*iter)->getNameAsString(); - offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i++); + + IVD->getNameAsString(); + offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, i); // Get the correct ivar field llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr( IvarList, offsetPointerIndexes, 4); - // Get the existing alias, if one exists. + // Get the existing variable, if one exists. llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name); if (offset) { offset->setInitializer(offsetValue); @@ -2142,12 +2143,18 @@ llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( // when linked against code which isn't (most of the time). llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name); if (!IvarOffsetPointer) { - uint64_t Offset; - if (ObjCImplementationDecl *OID = - CGM.getContext().getObjCImplementation( + // This will cause a run-time crash if we accidentally use it. A value of + // 0 would seem more sensible, but will silently overwrite the isa pointer + // causing a great deal of confusion. + uint64_t Offset = -1; + // We can't call ComputeIvarBaseOffset() here if we have the + // implementation, because it will create an invalid ASTRecordLayout object + // that we are then stuck with forever, so we only initialize the ivar + // offset variable with a guess if we only have the interface. The + // initializer will be reset later anyway, when we are generating the class + // description. + if (!CGM.getContext().getObjCImplementation( const_cast<ObjCInterfaceDecl *>(ID))) - Offset = ComputeIvarBaseOffset(CGM, OID, Ivar); - else Offset = ComputeIvarBaseOffset(CGM, ID, Ivar); llvm::ConstantInt *OffsetGuess = diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 098157474b..a1b029c320 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -77,6 +77,7 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, ++Index; } assert(Index != Ivars.size() && "Ivar is not inside container!"); + assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!"); return RL->getFieldOffset(Index); } -- 2.40.0