forked from OSchip/llvm-project
A selector match between two Objective-C methods does *not* guarantee
that the methods have the same number of parameters, although we certainly assumed this in many places. Objective-C can be insane sometimes. Fixes <rdar://problem/11460990>. llvm-svn: 157025
This commit is contained in:
parent
097e37da0e
commit
0bf70f4be8
|
@ -2227,10 +2227,11 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,
|
|||
mergeDeclAttributes(newMethod, oldMethod, mergeDeprecation);
|
||||
|
||||
// Merge attributes from the parameters.
|
||||
ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin();
|
||||
ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(),
|
||||
oe = oldMethod->param_end();
|
||||
for (ObjCMethodDecl::param_iterator
|
||||
ni = newMethod->param_begin(), ne = newMethod->param_end();
|
||||
ni != ne; ++ni, ++oi)
|
||||
ni != ne && oi != oe; ++ni, ++oi)
|
||||
mergeParamDeclAttributes(*ni, *oi, Context);
|
||||
|
||||
CheckObjCMethodOverride(newMethod, oldMethod, true);
|
||||
|
|
|
@ -173,10 +173,11 @@ void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
|
|||
Diag(Overridden->getLocation(), diag::note_previous_decl)
|
||||
<< "method";
|
||||
}
|
||||
ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin();
|
||||
ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
|
||||
oe = Overridden->param_end();
|
||||
for (ObjCMethodDecl::param_iterator
|
||||
ni = NewMethod->param_begin(), ne = NewMethod->param_end();
|
||||
ni != ne; ++ni, ++oi) {
|
||||
ni != ne && oi != oe; ++ni, ++oi) {
|
||||
const ParmVarDecl *oldDecl = (*oi);
|
||||
ParmVarDecl *newDecl = (*ni);
|
||||
if (newDecl->hasAttr<NSConsumedAttr>() !=
|
||||
|
@ -1399,8 +1400,9 @@ void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
|
|||
true);
|
||||
|
||||
for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
|
||||
IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
|
||||
IM != EM; ++IM, ++IF) {
|
||||
IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
|
||||
EF = MethodDecl->param_end();
|
||||
IM != EM && IF != EF; ++IM, ++IF) {
|
||||
CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF,
|
||||
IsProtocolMethodDecl, false, true);
|
||||
}
|
||||
|
@ -1421,8 +1423,9 @@ void Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method,
|
|||
true);
|
||||
|
||||
for (ObjCMethodDecl::param_iterator IM = Method->param_begin(),
|
||||
IF = Overridden->param_begin(), EM = Method->param_end();
|
||||
IM != EM; ++IM, ++IF) {
|
||||
IF = Overridden->param_begin(), EM = Method->param_end(),
|
||||
EF = Overridden->param_end();
|
||||
IM != EM && IF != EF; ++IM, ++IF) {
|
||||
CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF,
|
||||
IsProtocolMethodDecl, true, true);
|
||||
}
|
||||
|
@ -1454,8 +1457,9 @@ void Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl,
|
|||
IsProtocolMethodDecl, false, false);
|
||||
if (match)
|
||||
for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
|
||||
IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
|
||||
IM != EM; ++IM, ++IF) {
|
||||
IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
|
||||
EF = MethodDecl->param_end();
|
||||
IM != EM && IF != EF; ++IM, ++IF) {
|
||||
match = CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl,
|
||||
*IM, *IF,
|
||||
IsProtocolMethodDecl, false, false);
|
||||
|
@ -1954,9 +1958,10 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,
|
|||
return false;
|
||||
|
||||
ObjCMethodDecl::param_const_iterator
|
||||
li = left->param_begin(), le = left->param_end(), ri = right->param_begin();
|
||||
li = left->param_begin(), le = left->param_end(), ri = right->param_begin(),
|
||||
re = right->param_end();
|
||||
|
||||
for (; li != le; ++li, ++ri) {
|
||||
for (; li != le && ri != re; ++li, ++ri) {
|
||||
assert(ri != right->param_end() && "Param mismatch");
|
||||
const ParmVarDecl *lparm = *li, *rparm = *ri;
|
||||
|
||||
|
@ -2673,9 +2678,9 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
|
|||
isa<ObjCInterfaceDecl>(overridden->getDeclContext())) {
|
||||
ObjCMethodDecl::param_iterator ParamI = ObjCMethod->param_begin(),
|
||||
E = ObjCMethod->param_end();
|
||||
ObjCMethodDecl::param_iterator PrevI = overridden->param_begin();
|
||||
for (; ParamI != E; ++ParamI, ++PrevI) {
|
||||
// Number of parameters are the same and is guaranteed by selector match.
|
||||
ObjCMethodDecl::param_iterator PrevI = overridden->param_begin(),
|
||||
PrevE = overridden->param_end();
|
||||
for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) {
|
||||
assert(PrevI != overridden->param_end() && "Param mismatch");
|
||||
QualType T1 = Context.getCanonicalType((*ParamI)->getType());
|
||||
QualType T2 = Context.getCanonicalType((*PrevI)->getType());
|
||||
|
|
|
@ -178,3 +178,9 @@ void test_inference() {
|
|||
return (id)self; // expected-warning {{returning 'Fail *' from a function with incompatible result type 'id<X>'}}
|
||||
}
|
||||
@end
|
||||
|
||||
// <rdar://problem/11460990>
|
||||
|
||||
@interface WeirdNSString : NSString
|
||||
- (id)initWithCString:(const char*)string, void *blah;
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue