ObjectiveC migrator: tighten the rules for when

inferring NS_RETURNS_RETAINED, etc., return annotations.
Do not infer if these annotations are implicit
from the naming convention. Also add inference for
NS_CONSUMES_SELF annotation.

llvm-svn: 190106
This commit is contained in:
Fariborz Jahanian 2013-09-05 23:04:33 +00:00
parent 53d0b492f5
commit c24879e2de
2 changed files with 33 additions and 9 deletions

View File

@ -996,7 +996,8 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
bool FuncIsReturnAnnotated = (FuncDecl->getAttr<CFReturnsRetainedAttr>() ||
FuncDecl->getAttr<CFReturnsNotRetainedAttr>() ||
FuncDecl->getAttr<NSReturnsRetainedAttr>() ||
FuncDecl->getAttr<NSReturnsNotRetainedAttr>());
FuncDecl->getAttr<NSReturnsNotRetainedAttr>() ||
FuncDecl->getAttr<NSReturnsAutoreleasedAttr>());
// Trivial case of when funciton is annotated and has no argument.
if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
@ -1072,12 +1073,24 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
AnnotationString = " CF_RETURNS_NOT_RETAINED";
}
else if (Ret.getObjKind() == RetEffect::ObjC) {
if (Ret.isOwned() &&
Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
AnnotationString = " NS_RETURNS_RETAINED";
else if (Ret.notOwned() &&
Ctx.Idents.get("NS_RETURNS_NOT_RETAINED").hasMacroDefinition())
AnnotationString = " NS_RETURNS_NOT_RETAINED";
ObjCMethodFamily OMF = MethodDecl->getMethodFamily();
switch (OMF) {
case clang::OMF_alloc:
case clang::OMF_new:
case clang::OMF_copy:
case clang::OMF_init:
case clang::OMF_mutableCopy:
break;
default:
if (Ret.isOwned() &&
Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
AnnotationString = " NS_RETURNS_RETAINED";
else if (Ret.notOwned() &&
Ctx.Idents.get("NS_RETURNS_NOT_RETAINED").hasMacroDefinition())
AnnotationString = " NS_RETURNS_NOT_RETAINED";
break;
}
}
if (AnnotationString) {
@ -1111,7 +1124,18 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
bool MethodIsReturnAnnotated = (MethodDecl->getAttr<CFReturnsRetainedAttr>() ||
MethodDecl->getAttr<CFReturnsNotRetainedAttr>() ||
MethodDecl->getAttr<NSReturnsRetainedAttr>() ||
MethodDecl->getAttr<NSReturnsNotRetainedAttr>());
MethodDecl->getAttr<NSReturnsNotRetainedAttr>() ||
MethodDecl->getAttr<NSReturnsAutoreleasedAttr>());
if (CE.getReceiver() == DecRefMsg &&
!MethodDecl->getAttr<NSConsumesSelfAttr>() &&
MethodDecl->getMethodFamily() != OMF_init &&
MethodDecl->getMethodFamily() != OMF_release &&
Ctx.Idents.get("NS_CONSUMES_SELF").hasMacroDefinition()) {
edit::Commit commit(*Editor);
commit.insertBefore(MethodDecl->getLocEnd(), " NS_CONSUMES_SELF");
Editor->commit(commit);
}
// Trivial case of when funciton is annotated and has no argument.
if (MethodIsReturnAnnotated &&

View File

@ -1368,7 +1368,7 @@ typedef NSString* MyStringTy;
- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning
- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning
- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning
- (NSString*) newString_auto NS_RETURNS_AUTORELEASED NS_RETURNS_NOT_RETAINED; // no-warning
- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning
- (NSString*) newStringNoAttr;
- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}}
- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED;