r178937 - Rework how ObjC method inherit deprecated/availability.

Ted Kremenek kremenek at apple.com
Fri Apr 5 17:34:27 PDT 2013


Author: kremenek
Date: Fri Apr  5 19:34:27 2013
New Revision: 178937

URL: http://llvm.org/viewvc/llvm-project?rev=178937&view=rev
Log:
Rework how ObjC method inherit deprecated/availability.

New rule:
- Method decls in @implementation are considered "redeclarations"
  and inherit deprecated/availability from the @interface.
- All other cases are consider overrides, which do not inherit
  deprecated/availability.  For example:

  (a) @interface redeclares a method in an adopted protocol.
  (b) A subclass redeclares a method in a superclass.
  (c) A protocol redeclares a method from another protocol it adopts.

The idea is that API authors should have the ability to easily
move availability/deprecated up and down a class/protocol hierarchy.
A redeclaration means that the availability/deprecation is a blank
slate.

Fixes <rdar://problem/13574571>

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/SemaObjC/attr-availability.m
    cfe/trunk/test/SemaObjC/property-deprecated-warning.m
    cfe/trunk/test/SemaObjC/property-noninherited-availability-attr.m

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=178937&r1=178936&r2=178937&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Apr  5 19:34:27 2013
@@ -2769,7 +2769,10 @@ void Sema::mergeObjCMethodDecls(ObjCMeth
                                 ObjCMethodDecl *oldMethod) {
 
   // Merge the attributes, including deprecated/unavailable
-  mergeDeclAttributes(newMethod, oldMethod, AMK_Override);
+  AvailabilityMergeKind MergeKind =
+    isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration
+                                                   : AMK_Override;
+  mergeDeclAttributes(newMethod, oldMethod, MergeKind);
 
   // Merge attributes from the parameters.
   ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(),

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=178937&r1=178936&r2=178937&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Apr  5 19:34:27 2013
@@ -2246,8 +2246,11 @@ AvailabilityAttr *Sema::mergeAvailabilit
       MergedObsoleted == Obsoleted)
     return NULL;
 
+  // Only create a new attribute if !Override, but we want to do
+  // the checking.
   if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
-                             MergedDeprecated, MergedObsoleted)) {
+                             MergedDeprecated, MergedObsoleted) &&
+      !Override) {
     return ::new (Context) AvailabilityAttr(Range, Context, Platform,
                                             Introduced, Deprecated,
                                             Obsoleted, IsUnavailable, Message,

Modified: cfe/trunk/test/SemaObjC/attr-availability.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-availability.m?rev=178937&r1=178936&r2=178937&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-availability.m (original)
+++ cfe/trunk/test/SemaObjC/attr-availability.m Fri Apr  5 19:34:27 2013
@@ -17,7 +17,7 @@
 
 // rdar://11475360
 @interface B : A
-- (void)method; // expected-note {{method 'method' declared here}}
+- (void)method; // NOTE: we expect 'method' to *not* inherit availability.
 - (void)overridden __attribute__((availability(macosx,introduced=10.4))); // expected-warning{{overriding method introduced after overridden method on OS X (10.4 vs. 10.3)}}
 - (void)overridden2 __attribute__((availability(macosx,introduced=10.2)));
 - (void)overridden3 __attribute__((availability(macosx,deprecated=10.4)));
@@ -28,7 +28,7 @@
 
 void f(A *a, B *b) {
   [a method]; // expected-warning{{'method' is deprecated: first deprecated in OS X 10.2}}
-  [b method]; // expected-warning {{'method' is deprecated: first deprecated in OS X 10.2}}
+  [b method]; // no-warning
   [a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}}
   [b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}}
 }

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=178937&r1=178936&r2=178937&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-deprecated-warning.m (original)
+++ cfe/trunk/test/SemaObjC/property-deprecated-warning.m Fri Apr  5 19:34:27 2013
@@ -5,37 +5,51 @@
 typedef signed char BOOL;
 
 @protocol P
- at property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{property 'ptarget' is declared deprecated here}}
+ at property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} expected-note {{method 'ptarget' declared here}}
 @end
 
 @protocol P1<P>
-- (void)setPtarget:(id)arg; // expected-note {{method 'setPtarget:' declared here}}
+- (void)setPtarget:(id)arg;
 @end
 
 
 @interface UITableViewCell<P1>
- at property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}}
+ at property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}} expected-note {{method 'setTarget:' declared here}}
 @end
 
 @interface PSTableCell : UITableViewCell
- - (void)setTarget:(id)target; // expected-note {{method 'setTarget:' declared here}}
+ - (void)setTarget:(id)target;
 @end
 
 @interface UITableViewCell(UIDeprecated)
- at property(nonatomic,assign) id dep_target  __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'dep_target' declared here}} \
-                                                                                    // expected-note 2 {{property 'dep_target' is declared deprecated here}} \
-                                                                                    // expected-note {{method 'setDep_target:' declared here}}
+ at property(nonatomic,assign) id dep_target  __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{method 'dep_target' declared here}} \
+                                                                                    // expected-note 4 {{property 'dep_target' is declared deprecated here}} \
+                                                                                    // expected-note 2 {{method 'setDep_target:' declared here}}
 @end
 
 @implementation PSTableCell
 - (void)setTarget:(id)target {};
 - (void)setPtarget:(id)val {};
 - (void) Meth {
+  [self setTarget: (id)0]; // no-warning
+  [self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \
+                                           // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}}
+					   
+  [self setPtarget: (id)0]; // no-warning
+}
+ at end
+
+ at implementation UITableViewCell
+ at synthesize target;
+ at synthesize ptarget;
+- (void)setPtarget:(id)val {};
+- (void)setTarget:(id)target {};
+- (void) Meth {
   [self setTarget: (id)0]; // expected-warning {{'setTarget:' is deprecated: first deprecated in iOS 3.0}}
   [self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \
                                            // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}}
 					   
-  [self setPtarget: (id)0]; // expected-warning {{setPtarget:' is deprecated: first deprecated in iOS 3.0}}
+  [self setPtarget: (id)0]; // no-warning
 }
 @end
 
@@ -56,9 +70,11 @@ void testCustomAccessorNames(CustomAcces
 @end
 
 @interface ProtocolInCategory (TheCategory) <P1>
-- (id)ptarget; // expected-note {{method 'ptarget' declared here}}
+- (id)ptarget;
 @end
 
-id useDeprecatedProperty(ProtocolInCategory *obj) {
-  return [obj ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
+id useDeprecatedProperty(ProtocolInCategory *obj, id<P> obj2, int flag) {
+  if (flag)
+    return [obj ptarget];  // no-warning
+  return [obj2 ptarget];   // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
 }

Modified: cfe/trunk/test/SemaObjC/property-noninherited-availability-attr.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-noninherited-availability-attr.m?rev=178937&r1=178936&r2=178937&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-noninherited-availability-attr.m (original)
+++ cfe/trunk/test/SemaObjC/property-noninherited-availability-attr.m Fri Apr  5 19:34:27 2013
@@ -5,7 +5,8 @@
 
 @interface NSObject @end
 @protocol myProtocol
- at property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8)));
+ at property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{method 'myProtocolProperty' declared here}} \
+                                                                                                        // expected-note {{property 'myProtocolProperty' is declared deprecated here}}
 @end
 
 @interface Foo : NSObject
@@ -15,18 +16,19 @@
 @end
 
 @interface Bar : Foo <myProtocol>
- at property int myProperty; // expected-note {{'myProperty' declared here}}
- at property int myProtocolProperty; // expected-note {{'myProtocolProperty' declared here}}
+ at property int myProperty;
+ at property int myProtocolProperty;
 @end
 
-void test(Foo *y, Bar *x) {
+void test(Foo *y, Bar *x, id<myProtocol> z) {
   y.myProperty = 0; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
   [y myProperty];   // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} 
 
   x.myProperty = 1; // no-warning
-  [x myProperty]; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
+  [x myProperty]; // no-warning
 
   x.myProtocolProperty = 0; // no-warning
 
-  [x myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
+  [x myProtocolProperty]; // no-warning
+  [z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
 }





More information about the cfe-commits mailing list