[Sema][ObjC] Warn about mismatches in attributes between overriding and

overridden methods when compiling for non-ARC.

Previously, clang would error out when compiling for ARC, but didn't
print any diagnostics when compiling for non-ARC.

This was pointed out in the patch review for attribute noescape:

https://reviews.llvm.org/D32210

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313717 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2017-09-20 05:39:18 +00:00
parent 2351bad637
commit cb0d01de81
5 changed files with 52 additions and 36 deletions

View File

@ -507,6 +507,9 @@ def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas,
PragmaClangAttribute, PragmaPack]>;
def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
def NSConsumedMismatch : DiagGroup<"nsconsumed-mismatch">;
def NSReturnsMismatch : DiagGroup<"nsreturns-mismatch">;
def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">;
def UnknownAttributes : DiagGroup<"unknown-attributes">;
def IgnoredAttributes : DiagGroup<"ignored-attributes">;

View File

@ -8244,12 +8244,12 @@ def err_c99_array_usage_cxx : Error<
"feature, not permitted in C++">;
def err_type_unsupported : Error<
"%0 is not supported on this target">;
def err_nsconsumed_attribute_mismatch : Error<
def warn_nsconsumed_attribute_mismatch : Warning<
"overriding method has mismatched ns_consumed attribute on its"
" parameter">;
def err_nsreturns_retained_attribute_mismatch : Error<
" parameter">, InGroup<NSConsumedMismatch>;
def warn_nsreturns_retained_attribute_mismatch : Warning<
"overriding method has mismatched ns_returns_%select{not_retained|retained}0"
" attributes">;
" attributes">, InGroup<NSReturnsMismatch>;
def note_getter_unavailable : Note<
"or because setter is declared here, but no getter method %0 is found">;

View File

@ -157,34 +157,36 @@ void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
diag::note_related_result_type_overridden);
}
if (getLangOpts().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";
}
ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
oe = Overridden->param_end();
for (ObjCMethodDecl::param_iterator
ni = NewMethod->param_begin(), ne = NewMethod->param_end();
ni != ne && oi != oe; ++ni, ++oi) {
const 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";
}
Diags.setSeverity(diag::warn_nsreturns_retained_attribute_mismatch,
diag::Severity::Error, SourceLocation());
Diags.setSeverity(diag::warn_nsconsumed_attribute_mismatch,
diag::Severity::Error, SourceLocation());
}
if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() !=
Overridden->hasAttr<NSReturnsRetainedAttr>())) {
Diag(NewMethod->getLocation(),
diag::warn_nsreturns_retained_attribute_mismatch) << 1;
Diag(Overridden->getLocation(), diag::note_previous_decl) << "method";
}
if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() !=
Overridden->hasAttr<NSReturnsNotRetainedAttr>())) {
Diag(NewMethod->getLocation(),
diag::warn_nsreturns_retained_attribute_mismatch) << 0;
Diag(Overridden->getLocation(), diag::note_previous_decl) << "method";
}
ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
oe = Overridden->param_end();
for (ObjCMethodDecl::param_iterator ni = NewMethod->param_begin(),
ne = NewMethod->param_end();
ni != ne && oi != oe; ++ni, ++oi) {
const ParmVarDecl *oldDecl = (*oi);
ParmVarDecl *newDecl = (*ni);
if (newDecl->hasAttr<NSConsumedAttr>() !=
oldDecl->hasAttr<NSConsumedAttr>()) {
Diag(newDecl->getLocation(), diag::warn_nsconsumed_attribute_mismatch);
Diag(oldDecl->getLocation(), diag::note_previous_decl) << "parameter";
}
}
}

View File

@ -1787,15 +1787,15 @@ CFArrayRef camel_copymachine() {
// rdar://problem/8024350
@protocol F18P
- (id) clone;
- (id) clone; // expected-note 2 {{method declared here}}
@end
@interface F18 : NSObject<F18P> @end
@interface F18(Cat)
- (id) clone NS_RETURNS_RETAINED;
- (id) clone NS_RETURNS_RETAINED; // expected-warning {{overriding method has mismatched ns_returns_retained attributes}}
@end
@implementation F18
- (id) clone {
- (id) clone { // expected-warning {{overriding method has mismatched ns_returns_retained attributes}}
return [F18 alloc];
}
@end

View File

@ -1,6 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 -DOBJCARC %s
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
// rdar://10187884
#ifdef OBJCARC
typedef void (^blk)(id arg1, __attribute((ns_consumed)) id arg2);
typedef void (^blk1)(__attribute((ns_consumed))id arg1, __attribute((ns_consumed)) id arg2);
blk a = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
@ -18,3 +20,12 @@ blk1 b2 = ^void (id arg1, __attribute((ns_consumed)) id arg2){}; // expected-err
blk1 c3 = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){};
blk1 d4 = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}}
#else
@interface Sub
-(void) m:(id)p; // expected-note {{parameter declared here}}
@end
@interface Super : Sub
-(void) m:(__attribute__((ns_consumed)) id)p; // expected-warning {{overriding method has mismatched ns_consumed attribute on its parameter}}
@end
#endif