Skip to content

Commit

Permalink
[CodeGen] Fix assertion failure in EmitCallArg.
Browse files Browse the repository at this point in the history
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
(cherry picked from commit afd3b93)

Conflicts:
lib/CodeGen/CGCall.cpp
  • Loading branch information
ahatanaka committed Jul 11, 2017
1 parent 60a12bf commit d08a136
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
9 changes: 8 additions & 1 deletion lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3334,6 +3334,14 @@ void CodeGenFunction::EmitCallArgs(
unsigned Idx = LeftToRight ? I : E - I - 1;
CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx;
if (!LeftToRight) MaybeEmitImplicitObjectSize(Idx, *Arg);
// 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]);
EmitNonNullArgCheck(Args.back().RV, ArgTypes[Idx], (*Arg)->getExprLoc(),
AC, ParamsToSkip + Idx);
Expand Down Expand Up @@ -3385,7 +3393,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);
}

Expand Down
28 changes: 28 additions & 0 deletions test/CodeGenObjC/parameterized_classes.m
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,31 @@ - (void)setDest:(NSObject *)a {
_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

0 comments on commit d08a136

Please sign in to comment.