summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/inlining/retain-count-self-init.m
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-08-24 00:06:12 +0000
committerAnna Zaks <ganna@apple.com>2012-08-24 00:06:12 +0000
commit3d5d3d3e2cba3762cc919f661a22189797d076cc (patch)
tree75486292995f1b1bcc2f262a7ce4d922caa63308 /clang/test/Analysis/inlining/retain-count-self-init.m
parent907f6b8c06f0bfdb345dd2ee480a50d1e489c7d8 (diff)
downloadbcm5719-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/retain-count-self-init.m')
-rw-r--r--clang/test/Analysis/inlining/retain-count-self-init.m68
1 files changed, 68 insertions, 0 deletions
diff --git a/clang/test/Analysis/inlining/retain-count-self-init.m b/clang/test/Analysis/inlining/retain-count-self-init.m
new file mode 100644
index 00000000000..ee8dbe391c4
--- /dev/null
+++ b/clang/test/Analysis/inlining/retain-count-self-init.m
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit -analyzer-ipa=dynamic-bifurcate -verify %s
+
+typedef signed char BOOL;
+typedef struct objc_class *Class;
+typedef struct objc_object {
+ Class isa;
+} *id;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {}
++(id)alloc;
++(id)new;
+- (oneway void)release;
+-(id)init;
+-(id)autorelease;
+-(id)copy;
+- (Class)class;
+-(id)retain;
+@end
+
+// We do not want to overhelm user with error messages in case they forgot to
+// assign to self and check that the result of [super init] is non-nil. So
+// stop tracking the receiver of init with respect to Retain Release checker.
+// radar://12115830
+@interface ParentOfCell : NSObject
+- (id)initWithInt: (int)inInt;
+@end
+@interface Cell : ParentOfCell{
+ int x;
+}
+- (id)init;
++ (void)test;
+@property int x;
+@end
+@implementation Cell
+@synthesize x;
+- (id) init {
+ [super init];
+ self.x = 3; // no-warning
+ return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self)}}
+}
+- (id) initWithInt: (int)inInt {
+ [super initWithInt: inInt];
+ self.x = inInt; // no-warning
+ return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self)}}
+}
+- (id) init2 {
+ [self init]; // The call [self init] is inlined. We will warn inside the inlined body.
+ self.x = 2; // no-warning
+ return self;
+}
+
+- (id) initWithIntGood: (int)inInt {
+ if (self = [super initWithInt: inInt]) {
+ self.x = inInt;
+ }
+ return self;
+}
++ (void) test {
+ Cell *sharedCell1 = [[Cell alloc] init];
+ [sharedCell1 release];
+ Cell *sharedCell2 = [[Cell alloc] initWithInt: 3];
+ [sharedCell2 release];
+ Cell *sharedCell3 = [[Cell alloc] initWithIntGood: 3];
+ [sharedCell3 release];
+}
+
+@end
+
OpenPOWER on IntegriCloud