Refine diagnostics for leaks reported when returning an object

via function/method with [CF,NS]_RETURNS_NOT_RETAINED.

Fixes <rdar://problem/11379000>.

llvm-svn: 163355
This commit is contained in:
Ted Kremenek 2012-09-06 23:03:07 +00:00
parent 713bbb78c6
commit 2a786959b1
2 changed files with 31 additions and 14 deletions

View File

@ -2262,21 +2262,29 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
// objects. Only "copy", "alloc", "retain" and "new" transfer ownership
// to the caller for NS objects.
const Decl *D = &EndN->getCodeDecl();
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
os << " is returned from a method whose name ('"
<< MD->getSelector().getAsString()
<< "') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'."
" This violates the naming convention rules"
" given in the Memory Management Guide for Cocoa";
}
os << (isa<ObjCMethodDecl>(D) ? " is returned from a method "
: " is returned from a function ");
if (D->getAttr<CFReturnsNotRetainedAttr>())
os << "that is annotated as CF_RETURNS_NOT_RETAINED";
else if (D->getAttr<NSReturnsNotRetainedAttr>())
os << "that is annotated as NS_RETURNS_NOT_RETAINED";
else {
const FunctionDecl *FD = cast<FunctionDecl>(D);
os << " is returned from a function whose name ('"
<< *FD
<< "') does not contain 'Copy' or 'Create'. This violates the naming"
" convention rules given in the Memory Management Guide for Core"
" Foundation";
}
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
os << "whose name ('" << MD->getSelector().getAsString()
<< "') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'."
" This violates the naming convention rules"
" given in the Memory Management Guide for Cocoa";
}
else {
const FunctionDecl *FD = cast<FunctionDecl>(D);
os << "whose name ('" << *FD
<< "') does not contain 'Copy' or 'Create'. This violates the naming"
" convention rules given in the Memory Management Guide for Core"
" Foundation";
}
}
}
else if (RV->getKind() == RefVal::ErrorGCLeakReturned) {
ObjCMethodDecl &MD = cast<ObjCMethodDecl>(EndN->getCodeDecl());

View File

@ -1341,6 +1341,15 @@ void testattr4() {
consume_cf(y);
}
@interface TestOwnershipAttr2 : NSObject
- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning
@end
@implementation TestOwnershipAttr2
- (NSString*) newString {
return [NSString alloc]; // expected-warning {{Potential leak of an object}}
}
@end
@interface MyClassTestCFAttr : NSObject {}
- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED;