forked from OSchip/llvm-project
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:
parent
0070c6d4db
commit
ac8dbf0fc7
|
@ -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">;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue