]> granicus.if.org Git - clang/commitdiff
objcetive-c-arc: When overriding a method, its ns_consumed patameter
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 27 Sep 2011 22:35:36 +0000 (22:35 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 27 Sep 2011 22:35:36 +0000 (22:35 +0000)
attribute must match its overriden method. Same also for
ns_returns_retained/not_retained on the result type.
This is one half of // rdar://10187884

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

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/arc-decls.m

index b25b77c1869a25f8e12c9a185d89cf5e9c90dacf..d517c6aa35d9652329c84db10072791f9b6538ab 100644 (file)
@@ -4639,6 +4639,12 @@ def err_c99_array_usage_cxx : Error<
   "C99-specific array features are not permitted in C++">;
 def err_double_requires_fp64 : Error<
   "use of type 'double' requires cl_khr_fp64 extension to be enabled">;
+def err_nsconsumed_attribute_mismatch : Error<
+  "overriding method has mismatched ns_consumed attribute on its"
+  " parameter">;
+def err_nsreturns_retained_attribute_mismatch : Error<
+  "overriding method has mismatched ns_returns_%select{not_retained|retained}0"
+  " attributes">;
   
 def note_getter_unavailable : Note<
   "or because setter is declared here, but no getter method %0 is found">;
index f4ef5910dcfb476d8d71041fce4883e32f54c3cd..687bb5fa15bea7e74b008d05a65e040c7fbe8aa3 100644 (file)
@@ -5301,9 +5301,7 @@ public:
   
   /// \brief Check whether the given new method is a valid override of the
   /// given overridden method, and set any properties that should be inherited.
-  ///
-  /// \returns True if an error occurred.
-  bool CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, 
+  void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, 
                                const ObjCMethodDecl *Overridden,
                                bool IsImplementation);
 
index 57201809f01d1769c329950fb887bc68c69c2ce9..0822edf7049a693264125c4924d203fa71c08e50 100644 (file)
@@ -106,7 +106,7 @@ bool Sema::checkInitMethod(ObjCMethodDecl *method,
   return true;
 }
 
-bool Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, 
+void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, 
                                    const ObjCMethodDecl *Overridden,
                                    bool IsImplementation) {
   if (Overridden->hasRelatedResultType() && 
@@ -156,8 +156,35 @@ bool Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
       Diag(Overridden->getLocation(), 
            diag::note_related_result_type_overridden);
   }
-  
-  return false;
+  if (getLangOptions().ObjCAutoRefCount) {
+    if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() !=
+         Overridden->hasAttr<NSReturnsRetainedAttr>())) {
+        Diag(NewMethod->getLocation(),
+             diag::err_nsreturns_retained_attribute_mismatch) << 1;
+        Diag(Overridden->getLocation(), diag::note_previous_decl) 
+        << "method";
+    }
+    if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() !=
+              Overridden->hasAttr<NSReturnsNotRetainedAttr>())) {
+        Diag(NewMethod->getLocation(),
+             diag::err_nsreturns_retained_attribute_mismatch) << 0;
+        Diag(Overridden->getLocation(), diag::note_previous_decl) 
+        << "method";
+    }
+    for (ObjCMethodDecl::param_iterator oi = Overridden->param_begin(),
+         ni = NewMethod->param_begin(), ne = NewMethod->param_end();
+         ni != ne; ++ni, ++oi) {
+      ParmVarDecl *oldDecl = (*oi);
+      ParmVarDecl *newDecl = (*ni);
+      if (newDecl->hasAttr<NSConsumedAttr>() != 
+          oldDecl->hasAttr<NSConsumedAttr>()) {
+        Diag(newDecl->getLocation(),
+             diag::err_nsconsumed_attribute_mismatch);
+        Diag(oldDecl->getLocation(), diag::note_previous_decl) 
+          << "parameter";
+      }
+    }
+  }
 }
 
 /// \brief Check a method declaration for compatibility with the Objective-C
index e713d239a0cfbda668b81a634079fc23d3178d4e..ec2e10fc067cdb9fc0e892e3b3d161409265ba2d 100644 (file)
@@ -62,3 +62,22 @@ void func()
 - new {return 0; };
 @end
 
+
+// rdar://10187884
+@interface Super
+- (void)bar:(id)b; // expected-note {{parameter declared here}}
+- (void)bar1:(id) __attribute((ns_consumed)) b;
+- (void)ok:(id) __attribute((ns_consumed)) b;
+- (id)ns_non; // expected-note {{method declared here}}
+- (id)not_ret:(id) b __attribute((ns_returns_not_retained)); // expected-note {{method declared here}}
+- (id)both__returns_not_retained:(id) b __attribute((ns_returns_not_retained));
+@end
+
+@interface Sub : Super
+- (void)bar:(id) __attribute((ns_consumed)) b; // expected-error {{overriding method has mismatched ns_consumed attribute on its parameter}}
+- (void)bar1:(id)b;
+- (void)ok:(id) __attribute((ns_consumed)) b;
+- (id)ns_non __attribute((ns_returns_not_retained)); // expected-error {{overriding method has mismatched ns_returns_not_retained attributes}}
+- (id)not_ret:(id) b __attribute((ns_returns_retained)); // expected-error {{overriding method has mismatched ns_returns_retained attributes}}
+- (id)both__returns_not_retained:(id) b __attribute((ns_returns_not_retained));
+@end