From: Ted Kremenek Date: Thu, 6 Sep 2012 23:03:07 +0000 (+0000) Subject: Refine diagnostics for leaks reported when returning an object X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec9f36ea83e0f57683dceaa53163f6246d1442d5;p=clang Refine diagnostics for leaks reported when returning an object via function/method with [CF,NS]_RETURNS_NOT_RETAINED. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163355 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 176f618a2b..e95ba52f69 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -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(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(D) ? " is returned from a method " + : " is returned from a function "); + + if (D->getAttr()) + os << "that is annotated as CF_RETURNS_NOT_RETAINED"; + else if (D->getAttr()) + os << "that is annotated as NS_RETURNS_NOT_RETAINED"; else { - const FunctionDecl *FD = cast(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(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(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(EndN->getCodeDecl()); diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 49a6bce4f3..9d2aa756b2 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -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;