ahatanak created this revision.

The assertion is checking that the types of the parameter and argument match. 
It fails when a method of a parameterized class is called. To fix the failure, 
this patch moves the assertion in EmitCallArg to its only caller EmitCallArgs.

Instead of moving the assertion, it's also possible to call substObjCMemberType 
in EmitCallArgs (the template function in CodeGenFunction.h) to compute the 
correct parameter type and pass it down.

rdar://problem/32874473


https://reviews.llvm.org/D34665

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


Index: test/CodeGenObjC/parameterized_classes.m
===================================================================
--- test/CodeGenObjC/parameterized_classes.m
+++ test/CodeGenObjC/parameterized_classes.m
@@ -96,3 +96,31 @@
   _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
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -3387,6 +3387,14 @@
     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.
@@ -3447,7 +3455,6 @@
   if (const ObjCIndirectCopyRestoreExpr *CRE
         = dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
     assert(getLangOpts().ObjCAutoRefCount);
-    assert(getContext().hasSameUnqualifiedType(E->getType(), type));
     return emitWritebackArg(*this, args, CRE);
   }
 


Index: test/CodeGenObjC/parameterized_classes.m
===================================================================
--- test/CodeGenObjC/parameterized_classes.m
+++ test/CodeGenObjC/parameterized_classes.m
@@ -96,3 +96,31 @@
   _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
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -3387,6 +3387,14 @@
     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.
@@ -3447,7 +3455,6 @@
   if (const ObjCIndirectCopyRestoreExpr *CRE
         = dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
     assert(getLangOpts().ObjCAutoRefCount);
-    assert(getContext().hasSameUnqualifiedType(E->getType(), type));
     return emitWritebackArg(*this, args, CRE);
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to