mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-08 14:49:38 +00:00
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
This commit is contained in:
parent
4a78699c8c
commit
c62d16f304
@ -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(); }
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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() ||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user