summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-11-13 22:27:05 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-11-13 22:27:05 +0000
commitc62d16f30461df314e2339a2219eed3f19b4ca87 (patch)
tree7aa4c13fdd9d6a99f0c6a28838cd84c3e1105b04
parent4a78699c8ca7ed3be1e4f83fc50b13cbaa66c82b (diff)
downloadbcm5719-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.h8
-rw-r--r--clang/include/clang/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp17
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp3
-rw-r--r--clang/test/ARCMT/checking.m11
-rw-r--r--clang/test/SemaObjC/attr-deprecated.m20
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
+
OpenPOWER on IntegriCloud