aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-09-27 22:35:36 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-09-27 22:35:36 +0000
commit3240fe3b715327c8fda6f5a3bc8a092b1fce82a7 (patch)
treea87d63f3a1eec6a94408f52bb54908cb533d554c
parent7e5f112ca7410af93c7cdc07cf3a9dae15214300 (diff)
objcetive-c-arc: When overriding a method, its ns_consumed patameter
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td6
-rw-r--r--include/clang/Sema/Sema.h4
-rw-r--r--lib/Sema/SemaDeclObjC.cpp33
-rw-r--r--test/SemaObjC/arc-decls.m19
4 files changed, 56 insertions, 6 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b25b77c186..d517c6aa35 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">;
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index f4ef5910dc..687bb5fa15 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -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);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 57201809f0..0822edf704 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -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
diff --git a/test/SemaObjC/arc-decls.m b/test/SemaObjC/arc-decls.m
index e713d239a0..ec2e10fc06 100644
--- a/test/SemaObjC/arc-decls.m
+++ b/test/SemaObjC/arc-decls.m
@@ -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