[cfe-commits] r157025 - in /cfe/trunk: lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclObjC.cpp test/SemaObjC/related-result-type-inference.m

Douglas Gregor dgregor at apple.com
Fri May 25 20:01:56 PDT 2012


On May 24, 2012, at 3:17 AM, Erik Verbruggen <erikjv at me.com> wrote:

> Quite errr... surprising. I only understood the testcase after reading it like 3 times. I think we should add a warning for this (possibly off by default), because I can see a lot of people falling into this trap.

I'd be happy to add a warning, if only I could figure out why anyone would ever want to do this. 

  - Doug

> -- Erik
> 
> On 18 mei 2012, at 01:13, Douglas Gregor <dgregor at apple.com> wrote:
> 
>> Author: dgregor
>> Date: Thu May 17 18:13:29 2012
>> New Revision: 157025
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=157025&view=rev
>> Log:
>> 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>.
>> 
>> Modified:
>>   cfe/trunk/lib/Sema/SemaDecl.cpp
>>   cfe/trunk/lib/Sema/SemaDeclObjC.cpp
>>   cfe/trunk/test/SemaObjC/related-result-type-inference.m
>> 
>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=157025&r1=157024&r2=157025&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu May 17 18:13:29 2012
>> @@ -2227,10 +2227,11 @@
>>  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);
>> 
>> Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=157025&r1=157024&r2=157025&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu May 17 18:13:29 2012
>> @@ -173,10 +173,11 @@
>>        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 @@
>>                            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 @@
>>                            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 @@
>>                                      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 @@
>>    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 @@
>>        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());
>> 
>> Modified: cfe/trunk/test/SemaObjC/related-result-type-inference.m
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/related-result-type-inference.m?rev=157025&r1=157024&r2=157025&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/SemaObjC/related-result-type-inference.m (original)
>> +++ cfe/trunk/test/SemaObjC/related-result-type-inference.m Thu May 17 18:13:29 2012
>> @@ -178,3 +178,9 @@
>>  return (id)self; // expected-warning {{returning 'Fail *' from a function with incompatible result type 'id<X>'}}
>> }
>> @end
>> +
>> +// <rdar://problem/11460990>
>> +
>> + at interface WeirdNSString : NSString
>> +- (id)initWithCString:(const char*)string, void *blah;
>> + at end
>> 
>> 
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list