From: Jordy Rose Date: Sat, 17 Mar 2012 05:49:15 +0000 (+0000) Subject: [analyzer] Don't claim an object was returned with +1 retain count before counting... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=74b7b2b42dd710ccea78d86a47c979d4b2af7093;p=clang [analyzer] Don't claim an object was returned with +1 retain count before counting autoreleases. Fixes PR10376. (Also, 80-column violations.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152976 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index e01db9508f..390d86f0a9 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -2055,8 +2055,8 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N, if (PrevV.getKind() == RefVal::Released) { assert(GCEnabled && CurrV.getCount() > 0); - os << " The object is not eligible for garbage collection until the " - "retain count reaches 0 again."; + os << " The object is not eligible for garbage collection until " + "the retain count reaches 0 again."; } break; @@ -2066,8 +2066,12 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N, break; case RefVal::ReturnedOwned: - os << "Object returned to caller as an owning reference (single retain " - "count transferred to caller)"; + // Autoreleases can be applied after marking a node ReturnedOwned. + if (CurrV.getAutoreleaseCount()) + return NULL; + + os << "Object returned to caller as an owning reference (single " + "retain count transferred to caller)"; break; case RefVal::ReturnedNotOwned: diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m index adf40ec788..c3f5fcda44 100644 --- a/test/Analysis/retain-release-path-notes.m +++ b/test/Analysis/retain-release-path-notes.m @@ -123,4 +123,10 @@ CFTypeRef CFGetRuleViolation () { id result = [[Foo alloc] init]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +1 retain count}} return result; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'result' is returned from a method whose name ('getViolation') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa}} } + +- (id)copyAutorelease { + id result = [[Foo alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}} + [result autorelease]; // expected-note{{Object sent -autorelease message}} + return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object returned to caller with a +0 retain count}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} @end