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