retain-release-path-notes.m revision 17a38e2636a8b1ce473fc6504c4b16cb09db29f4
1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
2
3/***
4This file is for testing the path-sensitive notes for retain/release errors.
5Its goal is to have simple branch coverage of any path-based diagnostics,
6not to actually check all possible retain/release errors.
7
8This file includes notes that only appear in a ref-counted analysis. 
9GC-specific notes should go in retain-release-path-notes-gc.m.
10***/
11
12@interface NSObject
13+ (id)alloc;
14- (id)init;
15- (void)dealloc;
16
17- (Class)class;
18
19- (id)retain;
20- (void)release;
21- (void)autorelease;
22@end
23
24@interface Foo : NSObject
25- (id)methodWithValue;
26@property(retain) id propertyValue;
27@end
28
29typedef struct CFType *CFTypeRef;
30CFTypeRef CFRetain(CFTypeRef);
31void CFRelease(CFTypeRef);
32
33id NSMakeCollectable(CFTypeRef);
34CFTypeRef CFMakeCollectable(CFTypeRef);
35
36CFTypeRef CFCreateSomething();
37CFTypeRef CFGetSomething();
38
39
40void creationViaAlloc () {
41  id leaked = [[NSObject alloc] init]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +1 retain count}}
42  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
43}
44
45void creationViaCFCreate () {
46  CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
47  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
48}
49
50void acquisitionViaMethod (Foo *foo) {
51  id leaked = [foo methodWithValue]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +0 retain count}}
52  [leaked retain]; // expected-note{{Reference count incremented. The object now has a +1 retain count}}
53  [leaked retain]; // expected-note{{Reference count incremented. The object now has a +2 retain count}}
54  [leaked release]; // expected-note{{Reference count decremented. The object now has a +1 retain count}}
55  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
56}
57
58void acquisitionViaProperty (Foo *foo) {
59  id leaked = foo.propertyValue; // expected-warning{{leak}} expected-note{{Property returns an Objective-C object with a +0 retain count}}
60  [leaked retain]; // expected-note{{Reference count incremented. The object now has a +1 retain count}}
61  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
62}
63
64void acquisitionViaCFFunction () {
65  CFTypeRef leaked = CFGetSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count}}
66  CFRetain(leaked); // expected-note{{Reference count incremented. The object now has a +1 retain count}}
67  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
68}
69
70void explicitDealloc () {
71  id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
72  [object dealloc]; // expected-note{{Object released by directly sending the '-dealloc' message}}
73  [object class]; // expected-warning{{Reference-counted object is used after it is released}} // expected-note{{Reference-counted object is used after it is released}}
74}
75
76void implicitDealloc () {
77  id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
78  [object release]; // expected-note{{Object released}}
79  [object class]; // expected-warning{{Reference-counted object is used after it is released}} // expected-note{{Reference-counted object is used after it is released}}
80}
81
82void overAutorelease () {
83  id object = [[NSObject alloc] init]; // expected-note{{Method returns an Objective-C object with a +1 retain count}}
84  [object autorelease]; // expected-note{{Object sent -autorelease message}}
85  [object autorelease]; // expected-note{{Object sent -autorelease message}} 
86  return; // expected-warning{{Object sent -autorelease too many times}} expected-note{{Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count}} 
87}
88
89void autoreleaseUnowned (Foo *foo) {
90  id object = foo.propertyValue; // expected-note{{Property returns an Objective-C object with a +0 retain count}}
91  [object autorelease]; // expected-note{{Object sent -autorelease message}} 
92  return; // expected-warning{{Object sent -autorelease too many times}} expected-note{{Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count}}
93}
94
95void makeCollectableIgnored () {
96  CFTypeRef leaked = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count}}
97  CFMakeCollectable(leaked); // expected-note{{When GC is not enabled a call to 'CFMakeCollectable' has no effect on its argument}}
98  NSMakeCollectable(leaked); // expected-note{{When GC is not enabled a call to 'NSMakeCollectable' has no effect on its argument}}
99  return; // expected-note{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}}
100}
101
102CFTypeRef CFCopyRuleViolation () {
103  CFTypeRef object = CFGetSomething(); // expected-note{{Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain counte}}
104  return object; // 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}}
105}
106
107CFTypeRef CFGetRuleViolation () {
108  CFTypeRef object = CFCreateSomething(); // expected-warning{{leak}} expected-note{{Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain counte}}
109  return object; // 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 'object' is return from a function whose name ('CFGetRuleViolation') does not contain 'Copy' or 'Create'.  This violates the naming convention rules given the Memory Management Guide for Core Foundation}}
110}
111
112@implementation Foo (FundamentalMemoryManagementRules)
113- (id)copyViolation {
114  id result = self.propertyValue; // expected-note{{Property returns an Objective-C object with a +0 retain count}}
115  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}}
116}
117
118- (id)getViolation {
119  id result = [[Foo alloc] init]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +1 retain count}}
120  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}}
121}
122@end
123