objc-arc/mrc: Allow ns_returns_not_retained attribute on properties
to turn off warning on those properties which follow Cocoa naming
convention for retaining objects and yet they were not meant for
such purposes. Also, perform consistancy checking for declared
getters of such methods. // rdar://9636091



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133849 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 22f9b3e..012e256 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -737,6 +737,12 @@
         PIDecl->setGetterCXXConstructor(ResExpr);
       }
     }
+    if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
+        !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
+      Diag(getterMethod->getLocation(), 
+           diag::warn_property_getter_owning_mismatch);
+      Diag(property->getLocation(), diag::note_property_declare);
+    }
   }
   if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
     setterMethod->createImplicitParams(Context, IDecl);
@@ -1369,7 +1375,8 @@
       continue;
     
     const ObjCPropertyDecl *PD = PID->getPropertyDecl();
-    if (PD && !D->getInstanceMethod(PD->getGetterName())) {
+    if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() &&
+        !D->getInstanceMethod(PD->getGetterName())) {
       ObjCMethodDecl *method = PD->getGetterMethodDecl();
       if (!method)
         continue;
@@ -1465,6 +1472,9 @@
     // and the real context should be the same.
     if (lexicalDC)
       GetterMethod->setLexicalDeclContext(lexicalDC);
+    if (property->hasAttr<NSReturnsNotRetainedAttr>())
+      GetterMethod->addAttr(
+        ::new (Context) NSReturnsNotRetainedAttr(Loc, Context));
   } else
     // A user declared getter will be synthesize when @synthesize of
     // the property with the same name is seen in the @implementation