[CodeGen][ObjC] Fix assertion failure in EmitARCStoreStrongCall.

The assertion fails because EmitValueForIvarAtOffset doesn't get the
correct type of the ivar when the class the ivar belongs to is
parameterized. This commit fixes the function to compute the ivar's type
based on the type argument provided to the parameterized class.

rdar://problem/32461723

Differential Revision: https://reviews.llvm.org/D33698

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@304449 91177308-0d34-0410-b5e6-96231b3b80d8
(cherry picked from commit da3da60ded94f0ac960e711e96d96abdb7465a1f)
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
index 3da7ed2..136f642 100644
--- a/lib/CodeGen/CGObjCRuntime.cpp
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -90,7 +90,11 @@
                                                unsigned CVRQualifiers,
                                                llvm::Value *Offset) {
   // Compute (type*) ( (char *) BaseValue + Offset)
-  QualType IvarTy = Ivar->getType().withCVRQualifiers(CVRQualifiers);
+  QualType InterfaceTy{OID->getTypeForDecl(), 0};
+  QualType ObjectPtrTy =
+      CGF.CGM.getContext().getObjCObjectPointerType(InterfaceTy);
+  QualType IvarTy =
+      Ivar->getUsageType(ObjectPtrTy).withCVRQualifiers(CVRQualifiers);
   llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
   llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, CGF.Int8PtrTy);
   V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr");
diff --git a/test/CodeGenObjC/parameterized_classes.m b/test/CodeGenObjC/parameterized_classes.m
index b75cf2e..8fe5c52 100644
--- a/test/CodeGenObjC/parameterized_classes.m
+++ b/test/CodeGenObjC/parameterized_classes.m
@@ -68,3 +68,31 @@
   // CHECK: call i8* @objc_retainBlock
   // CHECK: ret void
 }
+
+// CHECK-LABEL: define internal void @"\01-[Derived setDest:]
+// CHECK: %[[SELFADDR:.*]] = alloca %[[SELFTY:.*]]*
+// CHECK: %[[AADDR:.*]] = alloca %[[IVARTY:.*]]*
+// CHECK: %[[V2:.*]] = load %[[IVARTY]]*, %[[IVARTY]]** %[[AADDR]]
+// CHECK: %[[V3:.*]] = load %[[SELFTY]]*, %[[SELFTY]]** %[[SELFADDR]]
+// CHECK: %[[IVAR:.*]] = load i64, i64* @"OBJC_IVAR_$_Base._destination"
+// CHECK: %[[V4:.*]] = bitcast %[[SELFTY]]* %[[V3]] to i8*
+// CHECK: %[[ADDPTR:.*]] = getelementptr inbounds i8, i8* %[[V4]], i64 %[[IVAR]]
+// CHECK: %[[V5:.*]] = bitcast i8* %[[ADDPTR]] to %[[IVARTY]]**
+// CHECK: %[[V6:.*]] = bitcast %[[IVARTY]]** %[[V5]] to i8**
+// CHECK: %[[V7:.*]] = bitcast %[[IVARTY]]* %[[V2]] to i8*
+// CHECK: call void @objc_storeStrong(i8** %[[V6]], i8* %[[V7]])
+
+@interface Base<DestType> : NSObject {
+  DestType _destination;
+}
+@end
+
+@interface Derived : Base<NSObject *>
+- (void)setDest:(NSObject *)a;
+@end
+
+@implementation Derived
+- (void)setDest:(NSObject *)a {
+  _destination = a;
+}
+@end