This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG61ae2db2d7a9: [analyzer] Adjust the reported variable name in retain count checker (authored by vsavchenko).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D100839/new/ https://reviews.llvm.org/D100839 Files: clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist clang/test/Analysis/osobject-retain-release.cpp clang/test/Analysis/retain-release-path-notes.m clang/test/Analysis/retain-release.m
Index: clang/test/Analysis/retain-release.m =================================================================== --- clang/test/Analysis/retain-release.m +++ clang/test/Analysis/retain-release.m @@ -2282,7 +2282,7 @@ void testAutoreleaseReturnsInput() { extern CFTypeRef CFCreateSomething(); - CFTypeRef obj = CFCreateSomething(); // expected-warning{{Potential leak of an object stored into 'obj'}} + CFTypeRef obj = CFCreateSomething(); // expected-warning{{Potential leak of an object stored into 'second'}} CFTypeRef second = CFAutorelease(obj); CFRetain(second); } @@ -2302,7 +2302,7 @@ } void autoreleaseReturningTypedObject() { - CFArrayRef arr = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Potential leak of an object stored into 'arr'}} + CFArrayRef arr = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Potential leak of an object stored into 'alias'}} CFArrayRef alias = (CFArrayRef)CFAutorelease((CFTypeRef)arr); CFRetain(alias); } Index: clang/test/Analysis/retain-release-path-notes.m =================================================================== --- clang/test/Analysis/retain-release-path-notes.m +++ clang/test/Analysis/retain-release-path-notes.m @@ -212,7 +212,7 @@ } -(id)initY { - self = [super init]; //expected-note {{Method returns an instance of MyObj with a +1 retain count}} + self = [super init]; // expected-note 6 {{Method returns an instance of MyObj with a +1 retain count}} return self; } @@ -327,5 +327,74 @@ @end +int seed(); +@interface LeakReassignmentTests : MyObj +@end + +@implementation LeakReassignmentTests ++(void)testLeakAliasSimple { + id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}} + // expected-note@-1 {{Returning from 'initY'}} + id New = Original; + Original = [[MyObj alloc] initZ]; + (void)New; + [Original release]; // expected-warning {{Potential leak of an object stored into 'New'}} + // expected-note@-1 {{Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1}} +} + ++(void)testLeakAliasChain { + id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}} + // expected-note@-1 {{Returning from 'initY'}} + id Intermediate = Original; + id New = Intermediate; + Original = [[MyObj alloc] initZ]; + (void)New; + [Original release]; // expected-warning {{Potential leak of an object stored into 'New'}} + // expected-note@-1 {{Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1}} +} + ++(void)log:(id)Obj with:(int)Num { + Num *= 42; + if (Obj ) + Num /= 2; +} + ++(int)calculate { + int x = 10; + int y = 25; + x += y * x + seed(); + return y - x * y; +} + ++(void)testLeakAliasDeathInExpr { + id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}} + // expected-note@-1 {{Returning from 'initY'}} + id New = Original; + Original = [[MyObj alloc] initZ]; + [self log:New with:[self calculate]]; + [Original release]; // expected-warning {{Potential leak of an object stored into 'New'}} + // expected-note@-1 {{Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1}} +} + ++(void)testLeakReassign { + id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}} + // expected-note@-1 {{Returning from 'initY'}} + // TODO: move warning here + Original = [[MyObj alloc] initZ]; + [Original release]; // expected-warning {{Potential leak of an object stored into 'Original'}} + // expected-note@-1 {{Object leaked: object allocated and stored into 'Original' is not referenced later in this execution path and has a retain count of +1}} +} + ++(void)testLeakReassign:(int)cond { + id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}} + // expected-note@-1 {{Returning from 'initY'}} + if (cond) // expected-note {{Assuming 'cond' is not equal to 0}} + // expected-note@-1 {{Taking true branch}} + // TODO: move warning here + Original = [[MyObj alloc] initZ]; + [Original release]; // expected-warning {{Potential leak of an object stored into 'Original'}} + // expected-note@-1 {{Object leaked: object allocated and stored into 'Original' is not referenced later in this execution path and has a retain count of +1}} +} +@end Index: clang/test/Analysis/osobject-retain-release.cpp =================================================================== --- clang/test/Analysis/osobject-retain-release.cpp +++ clang/test/Analysis/osobject-retain-release.cpp @@ -641,7 +641,7 @@ OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}} { OSObjectPtr p(obj); // expected-note{{Calling constructor for 'smart_ptr<OSObject>'}} - // expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}} + // expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}} // expected-note@os_smart_ptr.h:13{{Field 'pointer' is non-null}} // expected-note@os_smart_ptr.h:13{{Taking true branch}} // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}} @@ -653,9 +653,9 @@ // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}} // expected-note@os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}} // expected-note@os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}} - // expected-note@-6{{Returning from '~smart_ptr'}} -} // expected-warning{{Potential leak of an object stored into 'obj'}} -// expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}} + // expected-note@-6{{Returning from '~smart_ptr'}} +} // expected-warning{{Potential leak of an object stored into 'p'}} +// expected-note@-1{{Object leaked: object allocated and stored into 'p' is not referenced later in this execution path and has a retain count of +1}} void test_smart_ptr_no_leak() { OSObject *obj = new OSObject; Index: clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist =================================================================== --- clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist +++ clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist @@ -25476,12 +25476,12 @@ </dict> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'second' is not referenced later in this execution path and has a retain count of +1</string> <key>message</key> - <string>Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'second' is not referenced later in this execution path and has a retain count of +1</string> </dict> </array> - <key>description</key><string>Potential leak of an object stored into 'obj'</string> + <key>description</key><string>Potential leak of an object stored into 'second'</string> <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> <key>type</key><string>Leak</string> <key>check_name</key><string>osx.cocoa.RetainCount</string> @@ -25734,12 +25734,12 @@ </dict> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'alias' is not referenced later in this execution path and has a retain count of +1</string> <key>message</key> - <string>Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'alias' is not referenced later in this execution path and has a retain count of +1</string> </dict> </array> - <key>description</key><string>Potential leak of an object stored into 'arr'</string> + <key>description</key><string>Potential leak of an object stored into 'alias'</string> <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> <key>type</key><string>Leak</string> <key>check_name</key><string>osx.cocoa.RetainCount</string> Index: clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist =================================================================== --- clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist +++ clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist @@ -25407,12 +25407,12 @@ </dict> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'second' is not referenced later in this execution path and has a retain count of +1</string> <key>message</key> - <string>Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'second' is not referenced later in this execution path and has a retain count of +1</string> </dict> </array> - <key>description</key><string>Potential leak of an object stored into 'obj'</string> + <key>description</key><string>Potential leak of an object stored into 'second'</string> <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> <key>type</key><string>Leak</string> <key>check_name</key><string>osx.cocoa.RetainCount</string> @@ -25665,12 +25665,12 @@ </dict> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'alias' is not referenced later in this execution path and has a retain count of +1</string> <key>message</key> - <string>Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'alias' is not referenced later in this execution path and has a retain count of +1</string> </dict> </array> - <key>description</key><string>Potential leak of an object stored into 'arr'</string> + <key>description</key><string>Potential leak of an object stored into 'alias'</string> <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> <key>type</key><string>Leak</string> <key>check_name</key><string>osx.cocoa.RetainCount</string> Index: clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist =================================================================== --- clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist +++ clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist @@ -5012,6 +5012,1834 @@ </array> </dict> </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'initY'</string> + <key>message</key> + <string>Calling 'initY'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'testLeakAliasSimple'</string> + <key>message</key> + <string>Entered call from 'testLeakAliasSimple'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>21</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + <key>message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'initY'</string> + <key>message</key> + <string>Returning from 'initY'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>337</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>342</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>342</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>342</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>342</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>342</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1</string> + <key>message</key> + <string>Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1</string> + </dict> + </array> + <key>description</key><string>Potential leak of an object stored into 'New'</string> + <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> + <key>type</key><string>Leak</string> + <key>check_name</key><string>osx.cocoa.RetainCount</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>c6578d694dd90a2f586f52c9b53042c3</string> + <key>issue_context_kind</key><string>Objective-C method</string> + <key>issue_context</key><string>testLeakAliasSimple</string> + <key>issue_hash_function_offset</key><string>1</string> + <key>location</key> + <dict> + <key>line</key><integer>342</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>214</integer> + <integer>215</integer> + <integer>216</integer> + <integer>219</integer> + <integer>220</integer> + <integer>221</integer> + <integer>336</integer> + <integer>337</integer> + <integer>339</integer> + <integer>340</integer> + <integer>341</integer> + <integer>342</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'initY'</string> + <key>message</key> + <string>Calling 'initY'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'testLeakAliasChain'</string> + <key>message</key> + <string>Entered call from 'testLeakAliasChain'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>21</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + <key>message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'initY'</string> + <key>message</key> + <string>Returning from 'initY'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>347</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1</string> + <key>message</key> + <string>Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1</string> + </dict> + </array> + <key>description</key><string>Potential leak of an object stored into 'New'</string> + <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> + <key>type</key><string>Leak</string> + <key>check_name</key><string>osx.cocoa.RetainCount</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>076457f7cf482449386f129554f48f68</string> + <key>issue_context_kind</key><string>Objective-C method</string> + <key>issue_context</key><string>testLeakAliasChain</string> + <key>issue_hash_function_offset</key><string>1</string> + <key>location</key> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>214</integer> + <integer>215</integer> + <integer>216</integer> + <integer>219</integer> + <integer>220</integer> + <integer>221</integer> + <integer>346</integer> + <integer>347</integer> + <integer>349</integer> + <integer>350</integer> + <integer>351</integer> + <integer>352</integer> + <integer>353</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'initY'</string> + <key>message</key> + <string>Calling 'initY'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'testLeakAliasDeathInExpr'</string> + <key>message</key> + <string>Entered call from 'testLeakAliasDeathInExpr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>21</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + <key>message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'initY'</string> + <key>message</key> + <string>Returning from 'initY'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>371</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1</string> + <key>message</key> + <string>Object leaked: object allocated and stored into 'New' is not referenced later in this execution path and has a retain count of +1</string> + </dict> + </array> + <key>description</key><string>Potential leak of an object stored into 'New'</string> + <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> + <key>type</key><string>Leak</string> + <key>check_name</key><string>osx.cocoa.RetainCount</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>1ead75ff85eb09fa93374d0083f531e5</string> + <key>issue_context_kind</key><string>Objective-C method</string> + <key>issue_context</key><string>testLeakAliasDeathInExpr</string> + <key>issue_hash_function_offset</key><string>1</string> + <key>location</key> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>214</integer> + <integer>215</integer> + <integer>216</integer> + <integer>219</integer> + <integer>220</integer> + <integer>221</integer> + <integer>357</integer> + <integer>358</integer> + <integer>359</integer> + <integer>360</integer> + <integer>363</integer> + <integer>364</integer> + <integer>365</integer> + <integer>366</integer> + <integer>367</integer> + <integer>370</integer> + <integer>371</integer> + <integer>373</integer> + <integer>374</integer> + <integer>375</integer> + <integer>376</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'initY'</string> + <key>message</key> + <string>Calling 'initY'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'testLeakReassign'</string> + <key>message</key> + <string>Entered call from 'testLeakReassign'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>21</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + <key>message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'initY'</string> + <key>message</key> + <string>Returning from 'initY'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>381</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>385</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>385</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>385</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>385</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>385</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Object leaked: object allocated and stored into 'Original' is not referenced later in this execution path and has a retain count of +1</string> + <key>message</key> + <string>Object leaked: object allocated and stored into 'Original' is not referenced later in this execution path and has a retain count of +1</string> + </dict> + </array> + <key>description</key><string>Potential leak of an object stored into 'Original'</string> + <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> + <key>type</key><string>Leak</string> + <key>check_name</key><string>osx.cocoa.RetainCount</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>b258720b6e75b13188d9d8f67a8c328f</string> + <key>issue_context_kind</key><string>Objective-C method</string> + <key>issue_context</key><string>testLeakReassign</string> + <key>issue_hash_function_offset</key><string>1</string> + <key>location</key> + <dict> + <key>line</key><integer>385</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>214</integer> + <integer>215</integer> + <integer>216</integer> + <integer>219</integer> + <integer>220</integer> + <integer>221</integer> + <integer>380</integer> + <integer>381</integer> + <integer>384</integer> + <integer>385</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'initY'</string> + <key>message</key> + <string>Calling 'initY'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'testLeakReassign:'</string> + <key>message</key> + <string>Entered call from 'testLeakReassign:'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>214</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>21</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + <key>message</key> + <string>Method returns an instance of MyObj with a +1 retain count</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>215</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>216</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>37</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'initY'</string> + <key>message</key> + <string>Returning from 'initY'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>390</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>7</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>7</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>7</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Assuming 'cond' is not equal to 0</string> + <key>message</key> + <string>Assuming 'cond' is not equal to 0</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>7</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>392</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>395</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>395</integer> + <key>col</key><integer>12</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>395</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>395</integer> + <key>col</key><integer>12</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>396</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>396</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>396</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>396</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>396</integer> + <key>col</key><integer>11</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Object leaked: object allocated and stored into 'Original' is not referenced later in this execution path and has a retain count of +1</string> + <key>message</key> + <string>Object leaked: object allocated and stored into 'Original' is not referenced later in this execution path and has a retain count of +1</string> + </dict> + </array> + <key>description</key><string>Potential leak of an object stored into 'Original'</string> + <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> + <key>type</key><string>Leak</string> + <key>check_name</key><string>osx.cocoa.RetainCount</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>918946c323e2654da63c0d3b21f718fc</string> + <key>issue_context_kind</key><string>Objective-C method</string> + <key>issue_context</key><string>testLeakReassign:</string> + <key>issue_hash_function_offset</key><string>1</string> + <key>location</key> + <dict> + <key>line</key><integer>396</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>214</integer> + <integer>215</integer> + <integer>216</integer> + <integer>219</integer> + <integer>220</integer> + <integer>221</integer> + <integer>389</integer> + <integer>390</integer> + <integer>392</integer> + <integer>395</integer> + <integer>396</integer> + </array> + </dict> + </dict> </array> <key>files</key> <array> Index: clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist =================================================================== --- clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist +++ clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist @@ -21946,12 +21946,12 @@ </dict> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Object leaked: object allocated and stored into 'foo' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'garply' is not referenced later in this execution path and has a retain count of +1</string> <key>message</key> - <string>Object leaked: object allocated and stored into 'foo' is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'garply' is not referenced later in this execution path and has a retain count of +1</string> </dict> </array> - <key>description</key><string>Potential leak of an object stored into 'foo'</string> + <key>description</key><string>Potential leak of an object stored into 'garply'</string> <key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string> <key>type</key><string>Leak</string> <key>check_name</key><string>osx.cocoa.RetainCount</string> Index: clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h =================================================================== --- clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h +++ clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h @@ -68,17 +68,20 @@ }; class RefLeakReport : public RefCountReport { - const MemRegion* AllocBinding; - const Stmt *AllocStmt; + const MemRegion *AllocFirstBinding = nullptr; + const MemRegion *AllocBindingToReport = nullptr; + const Stmt *AllocStmt = nullptr; PathDiagnosticLocation Location; // Finds the function declaration where a leak warning for the parameter // 'sym' should be raised. - void deriveParamLocation(CheckerContext &Ctx, SymbolRef sym); - // Finds the location where a leak warning for 'sym' should be raised. - void deriveAllocLocation(CheckerContext &Ctx, SymbolRef sym); + void deriveParamLocation(CheckerContext &Ctx); + // Finds the location where the leaking object is allocated. + void deriveAllocLocation(CheckerContext &Ctx); // Produces description of a leak warning which is printed on the console. void createDescription(CheckerContext &Ctx); + // Finds the binding that we should use in a leak warning. + void findBindingToReport(CheckerContext &Ctx, ExplodedNode *Node); public: RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n, Index: clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -13,6 +13,8 @@ #include "RetainCountDiagnostics.h" #include "RetainCountChecker.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" using namespace clang; using namespace ento; @@ -337,15 +339,15 @@ class RefLeakReportVisitor : public RefCountReportVisitor { public: - RefLeakReportVisitor(SymbolRef Sym, const MemRegion *FirstBinding) - : RefCountReportVisitor(Sym), FirstBinding(FirstBinding) {} + RefLeakReportVisitor(SymbolRef Sym, const MemRegion *LastBinding) + : RefCountReportVisitor(Sym), LastBinding(LastBinding) {} PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR) override; private: - const MemRegion *FirstBinding; + const MemRegion *LastBinding; }; } // end namespace retaincountchecker @@ -614,6 +616,41 @@ return None; } +using Bindings = llvm::SmallVector<const MemRegion *, 4>; + +class VarBindingsCollector : public StoreManager::BindingsHandler { + SymbolRef Sym; + Bindings &Result; + +public: + VarBindingsCollector(SymbolRef Sym, Bindings &ToFill) + : Sym(Sym), Result(ToFill) {} + + bool HandleBinding(StoreManager &SMgr, Store Store, const MemRegion *R, + SVal Val) override { + SymbolRef SymV = Val.getAsLocSymbol(); + if (!SymV || SymV != Sym) + return true; + + if (isa<NonParamVarRegion>(R)) + Result.push_back(R); + + return true; + } +}; + +Bindings getAllVarBindingsForSymbol(ProgramStateManager &Manager, + const ExplodedNode *Node, SymbolRef Sym) { + Bindings Result; + VarBindingsCollector Collector{Sym, Result}; + while (Result.empty() && Node) { + Manager.iterBindings(Node->getState(), Collector); + Node = Node->getFirstPred(); + } + + return Result; +} + namespace { // Find the first node in the current function context that referred to the // tracked symbol and the memory location that value was stored to. Note, the @@ -740,7 +777,7 @@ os << "Object leaked: "; - Optional<std::string> RegionDescription = describeRegion(FirstBinding); + Optional<std::string> RegionDescription = describeRegion(LastBinding); if (RegionDescription) { os << "object allocated and stored into '" << *RegionDescription << '\''; } else { @@ -749,7 +786,7 @@ } // Get the retain count. - const RefVal* RV = getRefBinding(EndN->getState(), Sym); + const RefVal *RV = getRefBinding(EndN->getState(), Sym); assert(RV); if (RV->getKind() == RefVal::ErrorLeakReturned) { @@ -790,14 +827,15 @@ " Foundation"; } else if (RV->getObjKind() == ObjKind::OS) { std::string FuncName = FD->getNameAsString(); - os << "whose name ('" << FuncName - << "') starts with '" << StringRef(FuncName).substr(0, 3) << "'"; + os << "whose name ('" << FuncName << "') starts with '" + << StringRef(FuncName).substr(0, 3) << "'"; } } } } else { os << " is not referenced later in this execution path and has a retain " - "count of +" << RV->getCount(); + "count of +" + << RV->getCount(); } return std::make_shared<PathDiagnosticEventPiece>(L, os.str()); @@ -819,16 +857,16 @@ addVisitor(std::make_unique<RefCountReportVisitor>(sym)); } -void RefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) { - const SourceManager& SMgr = Ctx.getSourceManager(); +void RefLeakReport::deriveParamLocation(CheckerContext &Ctx) { + const SourceManager &SMgr = Ctx.getSourceManager(); - if (!sym->getOriginRegion()) + if (!Sym->getOriginRegion()) return; - auto *Region = dyn_cast<DeclRegion>(sym->getOriginRegion()); + auto *Region = dyn_cast<DeclRegion>(Sym->getOriginRegion()); if (Region) { const Decl *PDecl = Region->getDecl(); - if (PDecl && isa<ParmVarDecl>(PDecl)) { + if (isa_and_nonnull<ParmVarDecl>(PDecl)) { PathDiagnosticLocation ParamLocation = PathDiagnosticLocation::create(PDecl, SMgr); Location = ParamLocation; @@ -838,8 +876,7 @@ } } -void RefLeakReport::deriveAllocLocation(CheckerContext &Ctx, - SymbolRef sym) { +void RefLeakReport::deriveAllocLocation(CheckerContext &Ctx) { // Most bug reports are cached at the location where they occurred. // With leaks, we want to unique them by the location where they were // allocated, and only report a single path. To do this, we need to find @@ -850,13 +887,13 @@ // same SourceLocation. const ExplodedNode *AllocNode = nullptr; - const SourceManager& SMgr = Ctx.getSourceManager(); + const SourceManager &SMgr = Ctx.getSourceManager(); AllocationInfo AllocI = - GetAllocationSite(Ctx.getStateManager(), getErrorNode(), sym); + GetAllocationSite(Ctx.getStateManager(), getErrorNode(), Sym); AllocNode = AllocI.N; - AllocBinding = AllocI.R; + AllocFirstBinding = AllocI.R; markInteresting(AllocI.InterestingMethodContext); // Get the SourceLocation for the allocation site. @@ -866,13 +903,12 @@ AllocStmt = AllocNode->getStmtForDiagnostics(); if (!AllocStmt) { - AllocBinding = nullptr; + AllocFirstBinding = nullptr; return; } - PathDiagnosticLocation AllocLocation = - PathDiagnosticLocation::createBegin(AllocStmt, SMgr, - AllocNode->getLocationContext()); + PathDiagnosticLocation AllocLocation = PathDiagnosticLocation::createBegin( + AllocStmt, SMgr, AllocNode->getLocationContext()); Location = AllocLocation; // Set uniqieing info, which will be used for unique the bug reports. The @@ -887,7 +923,8 @@ llvm::raw_string_ostream os(Description); os << "Potential leak of an object"; - Optional<std::string> RegionDescription = describeRegion(AllocBinding); + Optional<std::string> RegionDescription = + describeRegion(AllocBindingToReport); if (RegionDescription) { os << " stored into '" << *RegionDescription << '\''; } else { @@ -897,16 +934,59 @@ } } +void RefLeakReport::findBindingToReport(CheckerContext &Ctx, + ExplodedNode *Node) { + if (!AllocFirstBinding) + // If we don't have any bindings, we won't be able to find any + // better binding to report. + return; + + // If the original region still contains the leaking symbol... + if (Node->getState()->getSVal(AllocFirstBinding).getAsSymbol() == Sym) { + // ...it is the best binding to report. + AllocBindingToReport = AllocFirstBinding; + return; + } + + // At this point, we know that the original region doesn't contain the leaking + // when the actual leak happens. It means that it can be confusing for the + // user to see such description in the message. + // + // Let's consider the following example: + // Object *Original = allocate(...); + // Object *New = Original; + // Original = allocate(...); + // Original->release(); + // + // Complaining about a leaking object "stored into Original" might cause a + // rightful confusion because 'Original' is actually released. + // We should complain about 'New' instead. + Bindings AllVarBindings = + getAllVarBindingsForSymbol(Ctx.getStateManager(), Node, Sym); + + // While looking for the last var bindings, we can still find + // `AllocFirstBinding` to be one of them. In situations like this, + // it would still be the easiest case to explain to our users. + if (!AllVarBindings.empty() && + llvm::count(AllVarBindings, AllocFirstBinding) == 0) + // Let's pick one of them at random (if there is something to pick from). + AllocBindingToReport = AllVarBindings[0]; + else + AllocBindingToReport = AllocFirstBinding; +} + RefLeakReport::RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *N, SymbolRef Sym, CheckerContext &Ctx) : RefCountReport(D, LOpts, N, Sym, /*isLeak=*/true) { - deriveAllocLocation(Ctx, Sym); - if (!AllocBinding) - deriveParamLocation(Ctx, Sym); + deriveAllocLocation(Ctx); + findBindingToReport(Ctx, N); + + if (!AllocFirstBinding) + deriveParamLocation(Ctx); createDescription(Ctx); - addVisitor(std::make_unique<RefLeakReportVisitor>(Sym, AllocBinding)); + addVisitor(std::make_unique<RefLeakReportVisitor>(Sym, AllocBindingToReport)); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits