r211039 - Objective-C. Diagnose when property access is using declared

Fariborz Jahanian fjahanian at apple.com
Mon Jun 16 10:25:41 PDT 2014


Author: fjahanian
Date: Mon Jun 16 12:25:41 2014
New Revision: 211039

URL: http://llvm.org/viewvc/llvm-project?rev=211039&view=rev
Log:
Objective-C. Diagnose when property access is using declared
property accessor methods which have become deprecated
or available. // rdar://15951801

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/DelayedDiagnostic.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/DelayedDiagnostic.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaPseudoObject.cpp
    cfe/trunk/test/SemaObjC/property-deprecated-warning.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=211039&r1=211038&r2=211039&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jun 16 12:25:41 2014
@@ -3680,6 +3680,9 @@ def note_not_found_by_two_phase_lookup :
 def err_undeclared_use : Error<"use of undeclared %0">;
 def warn_deprecated : Warning<"%0 is deprecated">,
     InGroup<DeprecatedDeclarations>;
+def warn_property_method_deprecated :
+    Warning<"property access is using %0 method which is deprecated">,
+    InGroup<DeprecatedDeclarations>;
 def warn_deprecated_message : Warning<"%0 is deprecated: %1">,
     InGroup<DeprecatedDeclarations>;
 def warn_deprecated_fwdclass_message : Warning<
@@ -3689,6 +3692,8 @@ def warn_deprecated_def : Warning<
     "Implementing deprecated %select{method|class|category}0">,
     InGroup<DeprecatedImplementations>, DefaultIgnore;
 def err_unavailable : Error<"%0 is unavailable">;
+def err_property_method_unavailable :
+    Error<"property access is using %0 method which is unavailable">;
 def err_unavailable_message : Error<"%0 is unavailable: %1">;
 def warn_unavailable_fwdclass_message : Warning<
     "%0 may be unavailable because the receiver type is unknown">,

Modified: cfe/trunk/include/clang/Sema/DelayedDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DelayedDiagnostic.h?rev=211039&r1=211038&r2=211039&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DelayedDiagnostic.h (original)
+++ cfe/trunk/include/clang/Sema/DelayedDiagnostic.h Mon Jun 16 12:25:41 2014
@@ -127,7 +127,8 @@ public:
                                             const NamedDecl *D,
                                             const ObjCInterfaceDecl *UnknownObjCClass,
                                             const ObjCPropertyDecl  *ObjCProperty,
-                                            StringRef Msg);
+                                            StringRef Msg,
+                                            bool ObjCPropertyAccess);
 
 
   static DelayedDiagnostic makeAccess(SourceLocation Loc,
@@ -202,6 +203,10 @@ public:
   const ObjCPropertyDecl *getObjCProperty() const {
     return DeprecationData.ObjCProperty;
   }
+    
+  bool getObjCPropertyAccess() const {
+    return DeprecationData.ObjCPropertyAccess;
+  }
   
 private:
 
@@ -211,6 +216,7 @@ private:
     const ObjCPropertyDecl  *ObjCProperty;
     const char *Message;
     size_t MessageLen;
+    bool ObjCPropertyAccess;
   };
 
   struct FTD {

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=211039&r1=211038&r2=211039&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jun 16 12:25:41 2014
@@ -3211,7 +3211,8 @@ public:
                                NamedDecl *D, StringRef Message,
                                SourceLocation Loc,
                                const ObjCInterfaceDecl *UnknownObjCClass,
-                               const ObjCPropertyDecl  *ObjCProperty);
+                               const ObjCPropertyDecl  *ObjCProperty,
+                               bool ObjCPropertyAccess);
 
   void HandleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
 
@@ -3223,7 +3224,8 @@ public:
 
   bool CanUseDecl(NamedDecl *D);
   bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
-                         const ObjCInterfaceDecl *UnknownObjCClass=nullptr);
+                         const ObjCInterfaceDecl *UnknownObjCClass=nullptr,
+                         bool ObjCPropertyAccess=false);
   void NoteDeletedFunction(FunctionDecl *FD);
   std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
   bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,

Modified: cfe/trunk/lib/Sema/DelayedDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DelayedDiagnostic.cpp?rev=211039&r1=211038&r2=211039&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DelayedDiagnostic.cpp (original)
+++ cfe/trunk/lib/Sema/DelayedDiagnostic.cpp Mon Jun 16 12:25:41 2014
@@ -25,7 +25,8 @@ DelayedDiagnostic::makeAvailability(Sema
                                     const NamedDecl *D,
                                     const ObjCInterfaceDecl *UnknownObjCClass,
                                     const ObjCPropertyDecl  *ObjCProperty,
-                                    StringRef Msg) {
+                                    StringRef Msg,
+                                    bool ObjCPropertyAccess) {
   DelayedDiagnostic DD;
   switch (AD) {
     case Sema::AD_Deprecation:
@@ -48,6 +49,7 @@ DelayedDiagnostic::makeAvailability(Sema
 
   DD.DeprecationData.Message = MessageData;
   DD.DeprecationData.MessageLen = Msg.size();
+  DD.DeprecationData.ObjCPropertyAccess = ObjCPropertyAccess;
   return DD;
 }
 

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=211039&r1=211038&r2=211039&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Jun 16 12:25:41 2014
@@ -4850,7 +4850,8 @@ DoEmitAvailabilityWarning(Sema &S,
                           StringRef Message,
                           SourceLocation Loc,
                           const ObjCInterfaceDecl *UnknownObjCClass,
-                          const ObjCPropertyDecl *ObjCProperty) {
+                          const ObjCPropertyDecl *ObjCProperty,
+                          bool ObjCPropertyAccess) {
 
   // Diagnostics for deprecated or unavailable.
   unsigned diag, diag_message, diag_fwdclass_message;
@@ -4866,7 +4867,8 @@ DoEmitAvailabilityWarning(Sema &S,
     case DelayedDiagnostic::Deprecation:
       if (isDeclDeprecated(Ctx))
         return;
-      diag = diag::warn_deprecated;
+      diag = !ObjCPropertyAccess ? diag::warn_deprecated
+                                 : diag::warn_property_method_deprecated;
       diag_message = diag::warn_deprecated_message;
       diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
       property_note_select = /* deprecated */ 0;
@@ -4876,7 +4878,8 @@ DoEmitAvailabilityWarning(Sema &S,
     case DelayedDiagnostic::Unavailable:
       if (isDeclUnavailable(Ctx))
         return;
-      diag = diag::err_unavailable;
+      diag = !ObjCPropertyAccess ? diag::err_unavailable
+                                 : diag::err_property_method_unavailable;
       diag_message = diag::err_unavailable_message;
       diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
       property_note_select = /* unavailable */ 1;
@@ -4917,20 +4920,22 @@ void Sema::HandleDelayedAvailabilityChec
                             DD.getDeprecationMessage(),
                             DD.Loc,
                             DD.getUnknownObjCClass(),
-                            DD.getObjCProperty());
+                            DD.getObjCProperty(), false);
 }
 
 void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,
                                    NamedDecl *D, StringRef Message,
                                    SourceLocation Loc,
                                    const ObjCInterfaceDecl *UnknownObjCClass,
-                                   const ObjCPropertyDecl  *ObjCProperty) {
+                                   const ObjCPropertyDecl  *ObjCProperty,
+                                   bool ObjCPropertyAccess) {
   // Delay if we're currently parsing a declaration.
   if (DelayedDiagnostics.shouldDelayDiagnostics()) {
     DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(AD, Loc, D,
                                                                UnknownObjCClass,
                                                                ObjCProperty,
-                                                               Message));
+                                                               Message,
+                                                               ObjCPropertyAccess));
     return;
   }
 
@@ -4946,5 +4951,5 @@ void Sema::EmitAvailabilityWarning(Avail
   }
 
   DoEmitAvailabilityWarning(*this, K, Ctx, D, Message, Loc,
-                            UnknownObjCClass, ObjCProperty);
+                            UnknownObjCClass, ObjCProperty, ObjCPropertyAccess);
 }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=211039&r1=211038&r2=211039&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jun 16 12:25:41 2014
@@ -83,7 +83,8 @@ static void DiagnoseUnusedOfDecl(Sema &S
 
 static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S,
                               NamedDecl *D, SourceLocation Loc,
-                              const ObjCInterfaceDecl *UnknownObjCClass) {
+                              const ObjCInterfaceDecl *UnknownObjCClass,
+                              bool ObjCPropertyAccess) {
   // See if this declaration is unavailable or deprecated.
   std::string Message;
   AvailabilityResult Result = D->getAvailability(&Message);
@@ -113,13 +114,15 @@ static AvailabilityResult DiagnoseAvaila
     case AR_Deprecated:
       if (S.getCurContextAvailability() != AR_Deprecated)
         S.EmitAvailabilityWarning(Sema::AD_Deprecation,
-                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl);
+                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl,
+                                  ObjCPropertyAccess);
       break;
 
     case AR_Unavailable:
       if (S.getCurContextAvailability() != AR_Unavailable)
         S.EmitAvailabilityWarning(Sema::AD_Unavailable,
-                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl);
+                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl,
+                                  ObjCPropertyAccess);
       break;
 
     }
@@ -251,7 +254,8 @@ void Sema::MaybeSuggestAddingStaticToDec
 /// referenced), false otherwise.
 ///
 bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
-                             const ObjCInterfaceDecl *UnknownObjCClass) {
+                             const ObjCInterfaceDecl *UnknownObjCClass,
+                             bool ObjCPropertyAccess) {
   if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) {
     // If there were any diagnostics suppressed by template argument deduction,
     // emit them now.
@@ -296,7 +300,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *
         DeduceReturnType(FD, Loc))
       return true;
   }
-  DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass);
+  DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, ObjCPropertyAccess);
 
   DiagnoseUnusedOfDecl(*this, D, Loc);
 

Modified: cfe/trunk/lib/Sema/SemaPseudoObject.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaPseudoObject.cpp?rev=211039&r1=211038&r2=211039&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaPseudoObject.cpp (original)
+++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp Mon Jun 16 12:25:41 2014
@@ -696,7 +696,8 @@ ExprResult ObjCPropertyOpBuilder::buildG
     assert(InstanceReceiver);
     receiverType = InstanceReceiver->getType();
   }
-
+  if (!Getter->isImplicit())
+    S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true);
   // Build a message-send.
   ExprResult msg;
   if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
@@ -771,6 +772,8 @@ ExprResult ObjCPropertyOpBuilder::buildS
 
   // Build a message-send.
   ExprResult msg;
+  if (!Setter->isImplicit())
+    S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true);
   if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
       RefExpr->isObjectReceiver()) {
     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,

Modified: cfe/trunk/test/SemaObjC/property-deprecated-warning.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-deprecated-warning.m?rev=211039&r1=211038&r2=211039&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-deprecated-warning.m (original)
+++ cfe/trunk/test/SemaObjC/property-deprecated-warning.m Mon Jun 16 12:25:41 2014
@@ -78,3 +78,28 @@ id useDeprecatedProperty(ProtocolInCateg
     return [obj ptarget];  // no-warning
   return [obj2 ptarget];   // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
 }
+
+// rdar://15951801
+ at interface Foo
+{
+  int _x;
+}
+ at property(nonatomic,readonly) int x;
+- (void)setX:(int)x __attribute__ ((deprecated)); // expected-note 2 {{'setX:' has been explicitly marked deprecated here}}
+- (int)x __attribute__ ((unavailable)); // expected-note {{'x' has been explicitly marked unavailable here}}
+ at end
+
+ at implementation Foo
+- (void)setX:(int)x {
+	_x = x;
+}
+- (int)x {
+  return _x;
+}
+ at end
+
+void testUserAccessorAttributes(Foo *foo) {
+        [foo setX:5678]; // expected-warning {{'setX:' is deprecated}}
+	foo.x = foo.x; // expected-error {{property access is using 'x' method which is unavailable}} \
+		       // expected-warning {{property access is using 'setX:' method which is deprecated}}
+}





More information about the cfe-commits mailing list