r221933 - Objective-C. Fixes a regression caused by implementation

Fariborz Jahanian fjahanian at apple.com
Thu Nov 13 14:27:06 PST 2014


Author: fjahanian
Date: Thu Nov 13 16:27:05 2014
New Revision: 221933

URL: http://llvm.org/viewvc/llvm-project?rev=221933&view=rev
Log:
Objective-C. Fixes a regression caused by implementation
of new warning for deprecated method call for receiver
of type 'id'. This addresses rdar://18960378 where
unintended warnings being issued.

Modified:
    cfe/trunk/include/clang/Sema/ObjCMethodList.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/ARCMT/checking.m
    cfe/trunk/test/SemaObjC/attr-deprecated.m

Modified: cfe/trunk/include/clang/Sema/ObjCMethodList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ObjCMethodList.h?rev=221933&r1=221932&r2=221933&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ObjCMethodList.h (original)
+++ cfe/trunk/include/clang/Sema/ObjCMethodList.h Thu Nov 13 16:27:05 2014
@@ -23,12 +23,14 @@ class ObjCMethodDecl;
 /// ObjCMethodList - a linked list of methods with different signatures.
 struct ObjCMethodList {
   ObjCMethodDecl *Method;
+  /// \brief count of methods with same signature.
+  unsigned Count;
   /// \brief The next list object and 2 bits for extra info.
   llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits;
 
-  ObjCMethodList() : Method(nullptr) { }
-  ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C)
-    : Method(M), NextAndExtraBits(C, 0) { }
+  ObjCMethodList() : Method(nullptr), Count(0) { }
+  ObjCMethodList(ObjCMethodDecl *M, unsigned count, ObjCMethodList *C)
+    : Method(M), Count(count), NextAndExtraBits(C, 0) { }
 
   ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); }
   unsigned getBits() const { return NextAndExtraBits.getInt(); }

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=221933&r1=221932&r2=221933&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Nov 13 16:27:05 2014
@@ -2963,6 +2963,9 @@ public:
   bool CollectMultipleMethodsInGlobalPool(Selector Sel,
                                           SmallVectorImpl<ObjCMethodDecl*>& Methods,
                                           bool instance);
+    
+  bool AreMultipleMethodsInGlobalPool(Selector Sel,
+                                      bool instance);
 
 private:
   /// \brief - Returns a selector which best matches given argument list or

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=221933&r1=221932&r2=221933&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Nov 13 16:27:05 2014
@@ -2229,6 +2229,7 @@ void Sema::addMethodToGlobalList(ObjCMet
   if (List->Method == nullptr) {
     List->Method = Method;
     List->setNext(nullptr);
+      List->Count = Method->isDefined() ? 0 : 1;
     return;
   }
   
@@ -2242,12 +2243,14 @@ void Sema::addMethodToGlobalList(ObjCMet
 
     if (!MatchTwoMethodDeclarations(Method, List->Method))
       continue;
-    
+      
     ObjCMethodDecl *PrevObjCMethod = List->Method;
 
     // Propagate the 'defined' bit.
     if (Method->isDefined())
       PrevObjCMethod->setDefined(true);
+    else
+      ++List->Count;
     
     // If a method is deprecated, push it in the global pool.
     // This is used for better diagnostics.
@@ -2268,7 +2271,7 @@ void Sema::addMethodToGlobalList(ObjCMet
   // We have a new signature for an existing method - add it.
   // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
   ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
-  Previous->setNext(new (Mem) ObjCMethodList(Method, nullptr));
+  Previous->setNext(new (Mem) ObjCMethodList(Method, 0, nullptr));
 }
 
 /// \brief Read the contents of the method pool for a given selector from
@@ -2334,6 +2337,16 @@ bool Sema::CollectMultipleMethodsInGloba
   return (Methods.size() > 1);
 }
 
+bool Sema::AreMultipleMethodsInGlobalPool(Selector Sel,
+                                          bool instance) {
+  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
+  // Test for no method in the pool which should not trigger any warning by caller.
+  if (Pos == MethodPool.end())
+    return true;
+  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
+  return MethList.Count > 1;
+}
+
 ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
                                                bool receiverIdOrClass,
                                                bool warn, bool instance) {

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=221933&r1=221932&r2=221933&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Thu Nov 13 16:27:05 2014
@@ -2452,8 +2452,7 @@ ExprResult Sema::BuildInstanceMessage(Ex
         if (ObjCMethodDecl *BestMethod =
               SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod()))
           Method = BestMethod;
-          SmallVector<ObjCMethodDecl*, 4> Methods;
-          if (!CollectMultipleMethodsInGlobalPool(Sel, Methods, Method->isInstanceMethod()))
+          if (!AreMultipleMethodsInGlobalPool(Sel, Method->isInstanceMethod()))
             DiagnoseUseOfDecl(Method, SelLoc);
       }
     } else if (ReceiverType->isObjCClassType() ||

Modified: cfe/trunk/test/ARCMT/checking.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/checking.m?rev=221933&r1=221932&r2=221933&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/checking.m (original)
+++ cfe/trunk/test/ARCMT/checking.m Thu Nov 13 16:27:05 2014
@@ -14,9 +14,9 @@ typedef int BOOL;
 typedef unsigned NSUInteger;
 
 @protocol NSObject
-- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note {{'retain' has been explicitly marked unavailable here}}
+- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
 - (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
-- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note 4 {{'release' has been explicitly marked unavailable here}}
+- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
 - (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
 @end
 
@@ -74,20 +74,16 @@ id global_foo;
 
 void test1(A *a, BOOL b, struct UnsafeS *unsafeS) {
   [[a delegate] release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \
-			  // expected-error {{'release' is unavailable: not available in automatic reference counting mode}} \
                           // expected-error {{ARC forbids explicit message send}}
   [a.delegate release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \
-			// expected-error {{'release' is unavailable: not available in automatic reference counting mode}} \
                         // expected-error {{ARC forbids explicit message send}}
   [unsafeS->unsafeObj retain]; // expected-error {{it is not safe to remove 'retain' message on an __unsafe_unretained type}} \
                                // expected-error {{ARC forbids explicit message send}} \
                                // expected-error {{'retain' is unavailable}}
   id foo = [unsafeS->unsafeObj retain]; // no warning.
   [global_foo retain]; // expected-error {{it is not safe to remove 'retain' message on a global variable}} \
-		       // expected-error {{'retain' is unavailable: not available in automatic reference counting mode}} \
                        // expected-error {{ARC forbids explicit message send}}
   [global_foo release]; // expected-error {{it is not safe to remove 'release' message on a global variable}} \
-			// expected-error {{'release' is unavailable: not available in automatic reference counting mode}} \
                         // expected-error {{ARC forbids explicit message send}}
   [a dealloc];
   [a retain];
@@ -308,8 +304,7 @@ void rdar9491791(int p) {
 
 // rdar://9504750
 void rdar9504750(id p) {
-  RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} \
-		    // expected-error {{'release' is unavailable: not available in automatic reference counting mode}}
+  RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} 
 }
 
 // rdar://8939557

Modified: cfe/trunk/test/SemaObjC/attr-deprecated.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-deprecated.m?rev=221933&r1=221932&r2=221933&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-deprecated.m (original)
+++ cfe/trunk/test/SemaObjC/attr-deprecated.m Thu Nov 13 16:27:05 2014
@@ -238,3 +238,23 @@ const char * func() {
   return [PID cString]; // expected-warning {{'cString' is deprecated: first deprecated in OS X 10.4}}
 }
 
+// rdar://18960378
+ at interface NSObject
++ (instancetype)alloc;
+- (instancetype)init;
+ at end
+
+ at interface NSLocale
+- (instancetype)init __attribute__((unavailable));
+ at end
+
+ at interface PLBatteryProperties : NSObject
++ (id)properties;
+ at end
+
+ at implementation PLBatteryProperties
++ (id)properties {
+    return [[self alloc] init];
+}
+ at end
+





More information about the cfe-commits mailing list