diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2014-11-13 22:27:05 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2014-11-13 22:27:05 +0000 |
commit | c62d16f30461df314e2339a2219eed3f19b4ca87 (patch) | |
tree | 7aa4c13fdd9d6a99f0c6a28838cd84c3e1105b04 | |
parent | 4a78699c8ca7ed3be1e4f83fc50b13cbaa66c82b (diff) | |
download | bcm5719-llvm-c62d16f30461df314e2339a2219eed3f19b4ca87.tar.gz bcm5719-llvm-c62d16f30461df314e2339a2219eed3f19b4ca87.zip |
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.
llvm-svn: 221933
-rw-r--r-- | clang/include/clang/Sema/ObjCMethodList.h | 8 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 3 | ||||
-rw-r--r-- | clang/test/ARCMT/checking.m | 11 | ||||
-rw-r--r-- | clang/test/SemaObjC/attr-deprecated.m | 20 |
6 files changed, 47 insertions, 15 deletions
diff --git a/clang/include/clang/Sema/ObjCMethodList.h b/clang/include/clang/Sema/ObjCMethodList.h index 914d8e4f4ed..956e0882c5f 100644 --- a/clang/include/clang/Sema/ObjCMethodList.h +++ b/clang/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<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(); } diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5841b07911d..e5bdce4e6c9 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -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 diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 5a1903f2622..96106440c95 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/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<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::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/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 0730cf6e7bf..7cb3c0ad007 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -2452,8 +2452,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, 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() || diff --git a/clang/test/ARCMT/checking.m b/clang/test/ARCMT/checking.m index 76c44430767..6a7cf76c386 100644 --- a/clang/test/ARCMT/checking.m +++ b/clang/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/clang/test/SemaObjC/attr-deprecated.m b/clang/test/SemaObjC/attr-deprecated.m index d98fec1764b..4d54d5da057 100644 --- a/clang/test/SemaObjC/attr-deprecated.m +++ b/clang/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 + |