diff options
author | Anna Zaks <ganna@apple.com> | 2012-08-24 00:06:12 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-08-24 00:06:12 +0000 |
commit | 3d5d3d3e2cba3762cc919f661a22189797d076cc (patch) | |
tree | 75486292995f1b1bcc2f262a7ce4d922caa63308 /clang/test/Analysis/inlining/RetainCountExamples.m | |
parent | 907f6b8c06f0bfdb345dd2ee480a50d1e489c7d8 (diff) | |
download | bcm5719-llvm-3d5d3d3e2cba3762cc919f661a22189797d076cc.tar.gz bcm5719-llvm-3d5d3d3e2cba3762cc919f661a22189797d076cc.zip |
[analyzer] Make analyzer less aggressive when dealing with [self init].
With inlining, retain count checker starts tracking 'self' through the
init methods. The analyser results were too noisy if the developer
did not follow 'self = [super init]' pattern (which is common
especially in older code bases) - we reported self init anti-pattern AND
possible use-after-free. This patch teaches the retain count
checker to assume that [super init] does not fail when it's not consumed
by another expression. This silences the retain count warning that warns
about possibility of use-after-free when init fails, while preserving
all the other checking on 'self'.
llvm-svn: 162508
Diffstat (limited to 'clang/test/Analysis/inlining/RetainCountExamples.m')
-rw-r--r-- | clang/test/Analysis/inlining/RetainCountExamples.m | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/clang/test/Analysis/inlining/RetainCountExamples.m b/clang/test/Analysis/inlining/RetainCountExamples.m index 2b682c2b4bf..c48e7b068d8 100644 --- a/clang/test/Analysis/inlining/RetainCountExamples.m +++ b/clang/test/Analysis/inlining/RetainCountExamples.m @@ -30,4 +30,36 @@ typedef struct objc_object { void selfStaysLive() { SelfStaysLive *foo = [[SelfStaysLive alloc] init]; [foo release]; -}
\ No newline at end of file +} + +// Test that retain release checker warns on leaks and use-after-frees when +// self init is not enabled. +// radar://12115830 +@interface ParentOfCell : NSObject +- (id)initWithInt: (int)inInt; +@end +@interface Cell : ParentOfCell{ + int x; +} +- (id)initWithInt: (int)inInt; ++ (void)testOverRelease; ++ (void)testLeak; +@property int x; +@end +@implementation Cell +@synthesize x; +- (id) initWithInt: (int)inInt { + [super initWithInt: inInt]; + self.x = inInt; // no-warning + return self; // Self Init checker would produce a warning here. +} ++ (void) testOverRelease { + Cell *sharedCell3 = [[Cell alloc] initWithInt: 3]; + [sharedCell3 release]; + [sharedCell3 release]; // expected-warning {{Reference-counted object is used after it is released}} +} ++ (void) testLeak { + Cell *sharedCell4 = [[Cell alloc] initWithInt: 3]; // expected-warning {{leak}} +} +@end + |