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
This commit is contained in:
Fariborz Jahanian 2011-09-27 22:35:36 +00:00
parent 0070c6d4db
commit ac8dbf0fc7
4 changed files with 56 additions and 6 deletions

View 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">;

View 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);

View 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

View 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