diff options
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 17 | ||||
-rw-r--r-- | test/SemaObjC/weak-receiver-warn.m | 20 |
2 files changed, 36 insertions, 1 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 5ee3c7b8c9..1b0ba58084 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1347,6 +1347,9 @@ 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(); @@ -1369,6 +1372,20 @@ static void DiagnoseARCUseOfWeakReceiver(Sema &S, Expr *Receiver) { } } } + 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->isSynthesized()) { + Selector Sel = Method->getSelector(); + if (Sel.getNumArgs() == 0) + PDecl = + S.LookupPropertyDecl(Method->getClassInterface(), + Sel.getIdentifierInfoForSlot(0)); + if (PDecl) + T = PDecl->getType(); + } + } if (T.getObjCLifetime() == Qualifiers::OCL_Weak) { S.Diag(Loc, diag::warn_receiver_is_weak) diff --git a/test/SemaObjC/weak-receiver-warn.m b/test/SemaObjC/weak-receiver-warn.m index c2a5d48186..56d9bc10f9 100644 --- a/test/SemaObjC/weak-receiver-warn.m +++ b/test/SemaObjC/weak-receiver-warn.m @@ -15,7 +15,7 @@ void test0(Test0 *x) { [weakx addBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} [weakx setBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} - weakx.block = ^{ [x actNow]; }; + weakx.block = ^{ [x actNow]; }; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} } @interface Test @@ -48,3 +48,21 @@ void test0(Test0 *x) { @dynamic weak_prop, weak_atomic_prop; @end + +@interface MyClass { + __weak MyClass *_parent; +} +@property (weak) MyClass *parent; // expected-note 2 {{property declared here}} +@end + +@implementation MyClass +@synthesize parent = _parent; + +- (void)doSomething +{ + [[self parent] doSomething]; // expected-warning {{weak property may be unpredictably null in ARC mode}} + + (void)self.parent.doSomething; // expected-warning {{weak property may be unpredictably null in ARC mode}} +} + +@end |