From 5a9e57002331c7c566e38ee750d50cac1babc18f Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 13 Nov 2014 22:27:05 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221933 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/ObjCMethodList.h | 8 +++++--- include/clang/Sema/Sema.h | 3 +++ lib/Sema/SemaDeclObjC.cpp | 17 +++++++++++++++-- lib/Sema/SemaExprObjC.cpp | 3 +-- test/ARCMT/checking.m | 11 +++-------- test/SemaObjC/attr-deprecated.m | 20 ++++++++++++++++++++ 6 files changed, 47 insertions(+), 15 deletions(-) diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h index 914d8e4f4e..956e0882c5 100644 --- a/include/clang/Sema/ObjCMethodList.h +++ b/include/clang/Sema/ObjCMethodList.h @@ -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 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(); } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 5841b07911..e5bdce4e6c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2963,6 +2963,9 @@ public: bool CollectMultipleMethodsInGlobalPool(Selector Sel, SmallVectorImpl& Methods, bool instance); + + bool AreMultipleMethodsInGlobalPool(Selector Sel, + bool instance); private: /// \brief - Returns a selector which best matches given argument list or diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 5a1903f262..96106440c9 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -2229,6 +2229,7 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) { if (List->Method == nullptr) { List->Method = Method; List->setNext(nullptr); + List->Count = Method->isDefined() ? 0 : 1; return; } @@ -2242,12 +2243,14 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) { 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(ObjCMethodList *List, ObjCMethodDecl *Method) { // 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(); - 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::CollectMultipleMethodsInGlobalPool(Selector Sel, 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) { diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 0730cf6e7b..7cb3c0ad00 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -2452,8 +2452,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (ObjCMethodDecl *BestMethod = SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod())) Method = BestMethod; - SmallVector Methods; - if (!CollectMultipleMethodsInGlobalPool(Sel, Methods, Method->isInstanceMethod())) + if (!AreMultipleMethodsInGlobalPool(Sel, Method->isInstanceMethod())) DiagnoseUseOfDecl(Method, SelLoc); } } else if (ReceiverType->isObjCClassType() || diff --git a/test/ARCMT/checking.m b/test/ARCMT/checking.m index 76c4443076..6a7cf76c38 100644 --- a/test/ARCMT/checking.m +++ b/test/ARCMT/checking.m @@ -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 diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m index d98fec1764..4d54d5da05 100644 --- a/test/SemaObjC/attr-deprecated.m +++ b/test/SemaObjC/attr-deprecated.m @@ -238,3 +238,23 @@ const char * func() { return [PID cString]; // expected-warning {{'cString' is deprecated: first deprecated in OS X 10.4}} } +// rdar://18960378 +@interface NSObject ++ (instancetype)alloc; +- (instancetype)init; +@end + +@interface NSLocale +- (instancetype)init __attribute__((unavailable)); +@end + +@interface PLBatteryProperties : NSObject ++ (id)properties; +@end + +@implementation PLBatteryProperties ++ (id)properties { + return [[self alloc] init]; +} +@end + -- 2.50.1