Index: lib/CodeGen/CGObjCGNU.cpp
===================================================================
--- lib/CodeGen/CGObjCGNU.cpp	(revision 72080)
+++ lib/CodeGen/CGObjCGNU.cpp	(working copy)
@@ -101,6 +101,8 @@
       std::vector<llvm::Constant*> &V, const std::string &Name="");
   llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty,
       std::vector<llvm::Constant*> &V, const std::string &Name="");
+  llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
+      const ObjCIvarDecl *Ivar);
 public:
   CGObjCGNU(CodeGen::CodeGenModule &cgm);
   virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *);
@@ -822,6 +824,14 @@
   llvm::SmallVector<llvm::Constant*, 16> IvarNames;
   llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
   llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
+  
+  int superInstanceSize = 
+    Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8;
+  // For non-fragile ivars, set the instance size to 0 - {the size of just this
+  // class}.  The runtime will then set this to the correct value on load.
+  if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+    instanceSize = 0 - (instanceSize - superInstanceSize);
+  }
   for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
       endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
       // Store the name
@@ -832,7 +842,14 @@
       Context.getObjCEncodingForType((*iter)->getType(), TypeStr);
       IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
       // Get the offset
-      uint64_t Offset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter);
+      uint64_t Offset;
+      if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+		Offset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter) -
+			superInstanceSize;
+        ObjCIvarOffsetVariable(ClassDecl, *iter);
+      } else {
+        Offset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter);
+      }
       IvarOffsets.push_back(
           llvm::ConstantInt::get(llvm::Type::Int32Ty, Offset));
   }
@@ -1104,6 +1121,7 @@
         llvm::Type::VoidTy, Params, true), "__objc_exec_class");
   Builder.CreateCall(Register, Module);
   Builder.CreateRetVoid();
+
   return LoadFunction;
 }
 
@@ -1468,6 +1486,25 @@
   return;
 }
 
+llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
+                              const ObjCInterfaceDecl *ID,
+                              const ObjCIvarDecl *Ivar) {
+  const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
+    + '.' + Ivar->getNameAsString();
+  // Emit the variable with weak linkage and initialize it with what we think
+  // the correct value is.  This allows code compiled with non-fragile ivars to
+  // work correctly when linked against code which isn't (most of the time).
+  llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
+  if (!IvarOffsetGV) {
+    uint64_t Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
+    llvm::ConstantInt *OffsetGuess =
+      llvm::ConstantInt::get(LongTy, Offset, "ivar");
+    IvarOffsetGV = new llvm::GlobalVariable(LongTy, false,
+        llvm::GlobalValue::CommonLinkage, OffsetGuess, Name, &TheModule);
+  }
+  return IvarOffsetGV;
+}
+
 LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
                                        QualType ObjectTy,
                                        llvm::Value *BaseValue,
@@ -1481,8 +1518,13 @@
 llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
                          const ObjCInterfaceDecl *Interface,
                          const ObjCIvarDecl *Ivar) {
+  if (CGF.getContext().getLangOptions().ObjCNonFragileABI)
+  {
+    return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),
+        false, "ivar");
+  }
   uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
-  return llvm::ConstantInt::get(LongTy, Offset);
+  return llvm::ConstantInt::get(LongTy, Offset, "ivar");
 }
 
 CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){
