Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 942d4dd

Browse files
committed
[ObjC][ARC] Avoid -Warc-performSelector-leaks for performSelector variations
that became supported after r297019 The commit r297019 expanded the performSelector ObjC method family heuristic to ensure that -Wobjc-unsafe-perform-selector covers all performSelector variations. However, this made the -Warc-performSelector-leaks too noisy, as that warning produces mostly false positives since the selector is unknown. This commit reverts the ObjC method family heuristics introduced in r297019. This ensures that -Warc-performSelector-leaks isn't too noisy. The commit still preserves the coverage of -Wobjc-unsafe-perform-selector. rdar://31124629 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@298587 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 4b1bd05 commit 942d4dd

File tree

3 files changed

+16
-9
lines changed

3 files changed

+16
-9
lines changed

Diff for: lib/AST/DeclObjC.cpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -979,12 +979,11 @@ ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
979979
break;
980980

981981
case OMF_performSelector:
982-
if (!isInstanceMethod() ||
983-
!(getReturnType()->isObjCIdType() || getReturnType()->isVoidType()))
982+
if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
984983
family = OMF_None;
985984
else {
986985
unsigned noParams = param_size();
987-
if (noParams < 1 || noParams > 5)
986+
if (noParams < 1 || noParams > 3)
988987
family = OMF_None;
989988
else {
990989
ObjCMethodDecl::param_type_iterator it = param_type_begin();
@@ -993,11 +992,10 @@ ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
993992
family = OMF_None;
994993
break;
995994
}
996-
// The first type should generally always be 'id' or 'Thread *', the
997-
// other types can vary.
998-
if (noParams > 1) {
999-
ArgT = *(it + 1);
1000-
if (!ArgT->isObjCObjectPointerType()) {
995+
while (--noParams) {
996+
it++;
997+
ArgT = (*it);
998+
if (!ArgT->isObjCIdType()) {
1001999
family = OMF_None;
10021000
break;
10031001
}

Diff for: lib/Sema/SemaExprObjC.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -2272,7 +2272,8 @@ static void checkFoundationAPI(Sema &S, SourceLocation Loc,
22722272
bool IsClassObjectCall) {
22732273
// Check if this is a performSelector method that uses a selector that returns
22742274
// a record or a vector type.
2275-
if (Method->getMethodFamily() != OMF_performSelector || Args.empty())
2275+
if (Method->getSelector().getMethodFamily() != OMF_performSelector ||
2276+
Args.empty())
22762277
return;
22772278
const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
22782279
if (!SE)

Diff for: test/SemaObjC/arc-peformselector.m

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ @interface I : NSObject
1818
- (id)performSelector:(SEL)aSelector;
1919
- (id)performSelector:(SEL)aSelector withObject:(id)object;
2020
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
21+
22+
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(double)delay inModes:(I *)modes;
23+
2124
@end
2225

2326
@implementation I
@@ -33,10 +36,15 @@ - (id) Meth {
3336
return [self performSelector : @selector(PlusZero)];
3437
return [self performSelector : @selector(PlusOne)]; // expected-error {{performSelector names a selector which retains the object}}
3538

39+
// Avoid the unkown selector warning for more complicated performSelector
40+
// variations because it produces too many false positives.
41+
[self performSelector: sel1 withObject:0 afterDelay:0 inModes:0];
42+
3643
return [self performSelector: @selector(self)]; // No error, -self is not +1!
3744
}
3845

3946
- (id)performSelector:(SEL)aSelector { return 0; }
4047
- (id)performSelector:(SEL)aSelector withObject:(id)object { return 0; }
4148
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2 { return 0; }
49+
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(double)delay inModes:(I *)modes { }
4250
@end

0 commit comments

Comments
 (0)