]> granicus.if.org Git - clang/commitdiff
[CodeGen] Fix assertion failure in EmitCallArg.
authorAkira Hatanaka <ahatanaka@apple.com>
Wed, 28 Jun 2017 00:42:48 +0000 (00:42 +0000)
committerAkira Hatanaka <ahatanaka@apple.com>
Wed, 28 Jun 2017 00:42:48 +0000 (00:42 +0000)
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
test/CodeGenObjC/parameterized_classes.m

index 38d520a2beb0a7dfe2a722a88101f870d0866256..8795e4a8998942239399398f8242163dadc119b9 100644 (file)
@@ -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<ObjCIndirectCopyRestoreExpr>(*Arg) ||
+            getContext().hasSameUnqualifiedType((*Arg)->getType(),
+                                                ArgTypes[Idx]) ||
+            (isa<ObjCMethodDecl>(AC.getDecl()) &&
+             isObjCMethodWithTypeParams(cast<ObjCMethodDecl>(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<ObjCIndirectCopyRestoreExpr>(E)) {
     assert(getLangOpts().ObjCAutoRefCount);
-    assert(getContext().hasSameUnqualifiedType(E->getType(), type));
     return emitWritebackArg(*this, args, CRE);
   }
 
index 8fe5c52b8d39a1b681e8b05121bdd7d751617c4d..34aca35af313c6fc69948f2b06f3b38f7d4d477a 100644 (file)
@@ -96,3 +96,31 @@ void blockTest(NSMutableArray<void (^)(void)> *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<ObjectType> : NSObject
+- (void)m0:(ObjectType *)first;
+@end
+
+@interface C0 : NSObject
+-(void)foo1;
+@end
+
+@implementation C0 {
+  P0<NSString *> *x;
+}
+
+-(void)foo1 {
+  NSString *d;
+  [x m0:&d];
+}
+@end