forked from OSchip/llvm-project
[Objective-C Sema]. Remove -Wreceiver-is-weak warning.
It is incorrect and better warning is issued under -Warc-repeated-use-of-weak. rdar://16316934. llvm-svn: 231851
This commit is contained in:
parent
bdc6c83d24
commit
2954c67e4b
|
@ -889,10 +889,6 @@ def warn_dealloc_in_category : Warning<
|
|||
InGroup<DeallocInCategory>;
|
||||
def err_gc_weak_property_strong_type : Error<
|
||||
"weak attribute declared on a __strong type property in GC mode">;
|
||||
def warn_receiver_is_weak : Warning <
|
||||
"weak %select{receiver|property|implicit property}0 may be "
|
||||
"unpredictably set to nil">,
|
||||
InGroup<DiagGroup<"receiver-is-weak">>, DefaultIgnore;
|
||||
def note_arc_assign_to_strong : Note<
|
||||
"assign the value to a strong variable to keep the object alive during use">;
|
||||
def warn_arc_repeated_use_of_weak : Warning <
|
||||
|
|
|
@ -1509,64 +1509,6 @@ ObjCMethodDecl *Sema::LookupMethodInQualifiedType(Selector Sel,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static void DiagnoseARCUseOfWeakReceiver(Sema &S, Expr *Receiver) {
|
||||
if (!Receiver)
|
||||
return;
|
||||
|
||||
if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Receiver))
|
||||
Receiver = OVE->getSourceExpr();
|
||||
|
||||
Expr *RExpr = Receiver->IgnoreParenImpCasts();
|
||||
SourceLocation Loc = RExpr->getLocStart();
|
||||
QualType T = RExpr->getType();
|
||||
const ObjCPropertyDecl *PDecl = nullptr;
|
||||
const ObjCMethodDecl *GDecl = nullptr;
|
||||
if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(RExpr)) {
|
||||
RExpr = POE->getSyntacticForm();
|
||||
if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(RExpr)) {
|
||||
if (PRE->isImplicitProperty()) {
|
||||
GDecl = PRE->getImplicitPropertyGetter();
|
||||
if (GDecl) {
|
||||
T = GDecl->getReturnType();
|
||||
}
|
||||
}
|
||||
else {
|
||||
PDecl = PRE->getExplicitProperty();
|
||||
if (PDecl) {
|
||||
T = PDecl->getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RExpr)) {
|
||||
// See if receiver is a method which envokes a synthesized getter
|
||||
// backing a 'weak' property.
|
||||
ObjCMethodDecl *Method = ME->getMethodDecl();
|
||||
if (Method && Method->getSelector().getNumArgs() == 0) {
|
||||
PDecl = Method->findPropertyDecl();
|
||||
if (PDecl)
|
||||
T = PDecl->getType();
|
||||
}
|
||||
}
|
||||
|
||||
if (T.getObjCLifetime() != Qualifiers::OCL_Weak) {
|
||||
if (!PDecl)
|
||||
return;
|
||||
if (!(PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak))
|
||||
return;
|
||||
}
|
||||
|
||||
S.Diag(Loc, diag::warn_receiver_is_weak)
|
||||
<< ((!PDecl && !GDecl) ? 0 : (PDecl ? 1 : 2));
|
||||
|
||||
if (PDecl)
|
||||
S.Diag(PDecl->getLocation(), diag::note_property_declare);
|
||||
else if (GDecl)
|
||||
S.Diag(GDecl->getLocation(), diag::note_method_declared_at) << GDecl;
|
||||
|
||||
S.Diag(Loc, diag::note_arc_assign_to_strong);
|
||||
}
|
||||
|
||||
/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
|
||||
/// objective C interface. This is a property reference expression.
|
||||
ExprResult Sema::
|
||||
|
@ -2760,15 +2702,6 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
|||
}
|
||||
|
||||
if (getLangOpts().ObjCAutoRefCount) {
|
||||
// Do not warn about IBOutlet weak property receivers being set to null
|
||||
// as this cannot asynchronously happen.
|
||||
bool WarnWeakReceiver = true;
|
||||
if (isImplicit && Method)
|
||||
if (const ObjCPropertyDecl *PropertyDecl = Method->findPropertyDecl())
|
||||
WarnWeakReceiver = !PropertyDecl->hasAttr<IBOutletAttr>();
|
||||
if (WarnWeakReceiver)
|
||||
DiagnoseARCUseOfWeakReceiver(*this, Receiver);
|
||||
|
||||
// In ARC, annotate delegate init calls.
|
||||
if (Result->getMethodFamily() == OMF_init &&
|
||||
(SuperLoc.isValid() || isSelfExpr(Receiver))) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
|
||||
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -Wno-objc-root-class -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
|
||||
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-arc -Wno-objc-root-class -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
|
||||
// rdar://11448209
|
||||
|
||||
#define READONLY readonly
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -Wreceiver-is-weak -verify %s
|
||||
// rdar://10225276
|
||||
|
||||
@interface Test0
|
||||
- (void) setBlock: (void(^)(void)) block;
|
||||
- (void) addBlock: (void(^)(void)) block;
|
||||
- (void) actNow;
|
||||
@end
|
||||
|
||||
void test0(Test0 *x) {
|
||||
__weak Test0 *weakx = x;
|
||||
[x addBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
[x setBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
x.block = ^{ [weakx actNow]; }; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
|
||||
[weakx addBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
[weakx setBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
weakx.block = ^{ [x actNow]; }; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
}
|
||||
|
||||
@interface Test
|
||||
{
|
||||
__weak Test* weak_prop;
|
||||
}
|
||||
- (void) Meth;
|
||||
@property __weak Test* weak_prop; // expected-note {{property declared here}}
|
||||
@property (weak, atomic) id weak_atomic_prop; // expected-note {{property declared here}}
|
||||
- (__weak id) P; // expected-note {{method 'P' declared here}}
|
||||
@end
|
||||
|
||||
@implementation Test
|
||||
- (void) Meth {
|
||||
if (self.weak_prop) {
|
||||
self.weak_prop = 0;
|
||||
}
|
||||
if (self.weak_atomic_prop) {
|
||||
self.weak_atomic_prop = 0;
|
||||
}
|
||||
[self.weak_prop Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
id pi = self.P;
|
||||
|
||||
[self.weak_atomic_prop Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
|
||||
[self.P Meth]; // expected-warning {{weak implicit property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
}
|
||||
|
||||
- (__weak id) P { return 0; }
|
||||
@dynamic weak_prop, weak_atomic_prop;
|
||||
@end
|
||||
|
||||
|
||||
@interface MyClass {
|
||||
__weak MyClass *_parent;
|
||||
}
|
||||
@property (weak) MyClass *parent; // expected-note 4 {{property declared here}}
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
@synthesize parent = _parent;
|
||||
|
||||
- (void)doSomething
|
||||
{
|
||||
[[self parent] doSomething]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
|
||||
(void)self.parent.doSomething; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Weak properties on protocols can be synthesized by an adopting class.
|
||||
@protocol MyProtocol
|
||||
@property (weak) id object; // expected-note 2 {{property declared here}}
|
||||
@end
|
||||
|
||||
void testProtocol(id <MyProtocol> input) {
|
||||
[[input object] Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
[input.object Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
}
|
||||
|
||||
|
||||
@interface Subclass : MyClass
|
||||
// Unnecessarily redeclare -parent.
|
||||
- (id)parent;
|
||||
@end
|
||||
|
||||
@implementation Subclass
|
||||
|
||||
- (id)parent {
|
||||
return [super parent];
|
||||
}
|
||||
|
||||
- (void)doSomethingElse {
|
||||
[[self parent] doSomething]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
|
||||
(void)self.parent.doSomething; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}}
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
Reference in New Issue