r195259 - Refine 'deprecated' checking for Objective-C classes/methods.

Ted Kremenek kremenek at apple.com
Wed Nov 20 09:24:03 PST 2013


Author: kremenek
Date: Wed Nov 20 11:24:03 2013
New Revision: 195259

URL: http://llvm.org/viewvc/llvm-project?rev=195259&view=rev
Log:
Refine 'deprecated' checking for Objective-C classes/methods.

- If a deprecated class refers to another deprecated class, do not warn.
- @implementations of a deprecated class can refer to other deprecated things.

Fixes <rdar://problem/15407366> and <rdar://problem/15466783>.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaObjC/attr-deprecated.m

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=195259&r1=195258&r2=195259&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Nov 20 11:24:03 2013
@@ -12994,5 +12994,22 @@ Decl *Sema::getObjCDeclContext() const {
 
 AvailabilityResult Sema::getCurContextAvailability() const {
   const Decl *D = cast<Decl>(getCurObjCLexicalContext());
+  // If we are within an Objective-C method, we should consult
+  // both the availability of the method as well as the
+  // enclosing class.  If the class is (say) deprecated,
+  // the entire method is considered deprecated from the
+  // purpose of checking if the current context is deprecated.
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    AvailabilityResult R = MD->getAvailability();
+    if (R != AR_Available)
+      return R;
+    D = MD->getClassInterface();
+  }
+  // If we are within an Objective-c @implementation, it
+  // gets the same availability context as the @interface.
+  else if (const ObjCImplementationDecl *ID =
+            dyn_cast<ObjCImplementationDecl>(D)) {
+    D = ID->getClassInterface();
+  }
   return D->getAvailability();
 }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=195259&r1=195258&r2=195259&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Nov 20 11:24:03 2013
@@ -111,7 +111,8 @@ static AvailabilityResult DiagnoseAvaila
       break;
             
     case AR_Deprecated:
-      S.EmitDeprecationWarning(D, Message, Loc, UnknownObjCClass, ObjCPDecl);
+      if (S.getCurContextAvailability() != AR_Deprecated)
+        S.EmitDeprecationWarning(D, Message, Loc, UnknownObjCClass, ObjCPDecl);
       break;
             
     case AR_Unavailable:

Modified: cfe/trunk/test/SemaObjC/attr-deprecated.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-deprecated.m?rev=195259&r1=195258&r2=195259&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-deprecated.m (original)
+++ cfe/trunk/test/SemaObjC/attr-deprecated.m Wed Nov 20 11:24:03 2013
@@ -154,3 +154,41 @@ typedef NewI DeprI __attribute__((deprec
   return 0;
 }
 @end
+
+// <rdar://problem/15407366> and <rdar://problem/15466783>:
+// - Using deprecated class name inside class should not warn about deprecation.
+// - Implementations of deprecated classes should not result in deprecation warnings.
+__attribute__((deprecated))
+ at interface DeprecatedClassA
+ at end
+
+__attribute__((deprecated))
+ at interface DeprecatedClassB
+// The self-reference return value should not be
+// flagged as the use of a deprecated declaration.
++ (DeprecatedClassB *)sharedInstance; // no-warning
+
+// Since this class is deprecated, returning a reference
+// to another deprecated class is fine as they may
+// have been deprecated together.  From a user's
+// perspective they are all deprecated.
++ (DeprecatedClassA *)somethingElse; // no-warning
+ at end
+
+ at implementation DeprecatedClassB
++ (DeprecatedClassB *)sharedInstance
+{
+  // This self-reference should not
+  // be flagged as a use of a deprecated
+  // declaration.
+  static DeprecatedClassB *x; // no-warning
+  return x;
+}
++ (DeprecatedClassA *)somethingElse {
+  // Since this class is deprecated, referencing
+  // another deprecated class is also OK.
+  static DeprecatedClassA *x; // no-warning
+  return x;
+}
+
+ at end





More information about the cfe-commits mailing list