From afd3b93fc835d07303f8880c091dbd5306f5fb9c Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 28 Jun 2017 00:42:48 +0000 Subject: [PATCH] [CodeGen] Fix assertion failure in EmitCallArg. The assertion was failing when a method of a parameterized class was called and the types of the argument and parameter didn't match. To fix the failure, move the assertion in EmitCallArg to its only caller EmitCallArgs and require the argument and parameter types match only when the method is not parameterized. rdar://problem/32874473 Differential Revision: https://reviews.llvm.org/D34665 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306494 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCall.cpp | 9 +++++++- test/CodeGenObjC/parameterized_classes.m | 28 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 38d520a2be..8795e4a899 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -3389,6 +3389,14 @@ void CodeGenFunction::EmitCallArgs( unsigned Idx = LeftToRight ? I : E - I - 1; CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx; unsigned InitialArgSize = Args.size(); + // If *Arg is an ObjCIndirectCopyRestoreExpr, check that either the types of + // the argument and parameter match or the objc method is parameterized. + assert((!isa(*Arg) || + getContext().hasSameUnqualifiedType((*Arg)->getType(), + ArgTypes[Idx]) || + (isa(AC.getDecl()) && + isObjCMethodWithTypeParams(cast(AC.getDecl())))) && + "Argument and parameter types don't match"); EmitCallArg(Args, *Arg, ArgTypes[Idx]); // In particular, we depend on it being the last arg in Args, and the // objectsize bits depend on there only being one arg if !LeftToRight. @@ -3449,7 +3457,6 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, if (const ObjCIndirectCopyRestoreExpr *CRE = dyn_cast(E)) { assert(getLangOpts().ObjCAutoRefCount); - assert(getContext().hasSameUnqualifiedType(E->getType(), type)); return emitWritebackArg(*this, args, CRE); } diff --git a/test/CodeGenObjC/parameterized_classes.m b/test/CodeGenObjC/parameterized_classes.m index 8fe5c52b8d..34aca35af3 100644 --- a/test/CodeGenObjC/parameterized_classes.m +++ b/test/CodeGenObjC/parameterized_classes.m @@ -96,3 +96,31 @@ void blockTest(NSMutableArray *array, NSString *name) { _destination = a; } @end + +// CHECK-LABEL: define internal void @"\01-[C0 foo1]"( +// CHECK: {{.*}} = alloca +// CHECK: {{.*}} = alloca +// CHECK: %[[D:.*]] = alloca %[[TY:.*]]* +// CHECK: %[[TEMP:.*]] = alloca %[[TY]]* +// CHECK: %[[V4:.*]] = load %[[TY]]*, %[[TY]]** %[[D]] +// CHECK: store %[[TY]]* %[[V4]], %[[TY]]** %[[TEMP]] +// CHECK: %[[V7:.*]] = bitcast %[[TY]]** %[[TEMP]] to i8** +// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8**)*)(i8* %{{.*}}, i8* %{{.*}}, i8** %[[V7]]) + +@interface P0 : NSObject +- (void)m0:(ObjectType *)first; +@end + +@interface C0 : NSObject +-(void)foo1; +@end + +@implementation C0 { + P0 *x; +} + +-(void)foo1 { + NSString *d; + [x m0:&d]; +} +@end -- 2.50.1