]> granicus.if.org Git - clang/commitdiff
Objective-C ARC. Do not warn about properties with both
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 17 Jun 2014 23:35:13 +0000 (23:35 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 17 Jun 2014 23:35:13 +0000 (23:35 +0000)
IBOutlet and weak attributes when accessed being
unpredictably set to nil because usage of such properties
are always single threaded and its ivar cannot be set
to nil asynchronously. // rdar://15885642

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211132 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/ScopeInfo.cpp
lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaPseudoObject.cpp
test/SemaObjC/iboutlet.m

index d9b2ca310a89869c38e59dd8695748b026291315..4d079e705f625051fdf8c2bba87086c85c8ff9fc 100644 (file)
@@ -158,8 +158,14 @@ void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
 
   // Has this weak object been seen before?
   FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
-  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E))
-    Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
+  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    if (isa<OpaqueValueExpr>(RefExpr->getBase()))
+     Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
+    else {
+      markSafeWeakUse(RefExpr->getBase());
+      return;
+    }
+  }
   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
   else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
index ffb6b037ec0fc387a0a74495c744d7b53c8c304b..c6a7d7c13dcc3c3fc3e02aae62884c73bba10ff5 100644 (file)
@@ -2640,7 +2640,14 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
   }
 
   if (getLangOpts().ObjCAutoRefCount) {
-    DiagnoseARCUseOfWeakReceiver(*this, Receiver);
+    // 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 &&
index eaf170c176bcfbb31649868f9d41b0f9e28db7af..35684b4fa22a1b33259236c0b3045acd7311ac78 100644 (file)
@@ -542,7 +542,7 @@ bool ObjCPropertyOpBuilder::isWeakProperty() const {
   if (RefExpr->isExplicitProperty()) {
     const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
     if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
-      return true;
+      return !Prop->hasAttr<IBOutletAttr>();
 
     T = Prop->getType();
   } else if (Getter) {
@@ -816,13 +816,20 @@ ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
 
   // As a special case, if the method returns 'id', try to get
   // a better type from the property.
-  if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
-      result.get()->getType()->isObjCIdType()) {
+  if (RefExpr->isExplicitProperty() && result.get()->isRValue()) {
     QualType propType = RefExpr->getExplicitProperty()->getType();
-    if (const ObjCObjectPointerType *ptr
-          = propType->getAs<ObjCObjectPointerType>()) {
-      if (!ptr->isObjCIdType())
-        result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+    if (result.get()->getType()->isObjCIdType()) {
+      if (const ObjCObjectPointerType *ptr
+            = propType->getAs<ObjCObjectPointerType>()) {
+        if (!ptr->isObjCIdType())
+          result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+      }
+    }
+    if (S.getLangOpts().ObjCAutoRefCount) {
+      Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
+      if (LT == Qualifiers::OCL_Weak)
+        if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
+              S.getCurFunction()->markSafeWeakUse(RefExpr);
     }
   }
 
index 3c7f9581e663592924cfdab9b6b68216edf3dd40..63eac9af8a5204403911bd5b7a7a979d7fc37ef5 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s
-// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Wno-objc-root-class -verify %s
+// 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
 // rdar://11448209
 
 #define READONLY readonly
 @implementation RKTFHView
 @synthesize synthReadOnlyReadWrite=_synthReadOnlyReadWrite;
 @end
+
+// rdar://15885642
+@interface WeakOutlet 
+@property IBOutlet __weak WeakOutlet* WeakProp;
+@end
+
+WeakOutlet* func() {
+  __weak WeakOutlet* pwi;
+  pwi.WeakProp = (WeakOutlet*)0;
+  pwi.WeakProp = pwi.WeakProp;
+  return pwi.WeakProp;
+}