ahatanak created this revision.

The assertion fails because CGObjCRuntime::EmitValueForIvarAtOffset doesn't get 
the correct type of the ivar when the class the ivar belongs to is 
parameterized. It assigns the type of the ivar in the parameterized base class, 
instead of the type in the derived class, to IvarTy. This eventually causes an 
assertion failure in CodeGenFunction::EmitARCStoreStrongCall because of a 
mismatch between the types of the address and the value being stored.


https://reviews.llvm.org/D33698

Files:
  lib/CodeGen/CGObjCRuntime.cpp
  test/CodeGenObjC/parameterized_classes.m


Index: test/CodeGenObjC/parameterized_classes.m
===================================================================
--- test/CodeGenObjC/parameterized_classes.m
+++ 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
Index: lib/CodeGen/CGObjCRuntime.cpp
===================================================================
--- lib/CodeGen/CGObjCRuntime.cpp
+++ 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");


Index: test/CodeGenObjC/parameterized_classes.m
===================================================================
--- test/CodeGenObjC/parameterized_classes.m
+++ 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
Index: lib/CodeGen/CGObjCRuntime.cpp
===================================================================
--- lib/CodeGen/CGObjCRuntime.cpp
+++ 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");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to