diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2011-09-27 22:35:36 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-09-27 22:35:36 +0000 |
| commit | ac8dbf0fc70ca56fa6c7bda4e9b76323102ba65a (patch) | |
| tree | 5499b29c2232a5f268cd60f7e473daa11ab50a79 | |
| parent | 0070c6d4dbdf81147b69b8f721ea1b39e9421bb2 (diff) | |
| download | bcm5719-llvm-ac8dbf0fc70ca56fa6c7bda4e9b76323102ba65a.tar.gz bcm5719-llvm-ac8dbf0fc70ca56fa6c7bda4e9b76323102ba65a.zip | |
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
llvm-svn: 140649
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 | ||||
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 33 | ||||
| -rw-r--r-- | clang/test/SemaObjC/arc-decls.m | 19 |
4 files changed, 56 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b25b77c1869..d517c6aa35d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index f4ef5910dcf..687bb5fa15b 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 57201809f01..0822edf7049 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/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/clang/test/SemaObjC/arc-decls.m b/clang/test/SemaObjC/arc-decls.m index e713d239a0c..ec2e10fc067 100644 --- a/clang/test/SemaObjC/arc-decls.m +++ b/clang/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 |

