[cfe-commits] r154866 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp test/Analysis/self-init.m
Anna Zaks
ganna at apple.com
Mon Apr 16 14:51:09 PDT 2012
Author: zaks
Date: Mon Apr 16 16:51:09 2012
New Revision: 154866
URL: http://llvm.org/viewvc/llvm-project?rev=154866&view=rev
Log:
[analyzer] Fix a false alarm in SelfInitChecker (radar://11235991).
Along with it, fix a couple of other corner cases and add more tests.
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
cfe/trunk/test/Analysis/self-init.m
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp?rev=154866&r1=154865&r2=154866&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp Mon Apr 16 16:51:09 2012
@@ -183,9 +183,6 @@
void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg,
CheckerContext &C) const {
- CallOrObjCMessage MsgWrapper(msg, C.getState(), C.getLocationContext());
- checkPostStmt(MsgWrapper, C);
-
// When encountering a message that does initialization (init rule),
// tag the return value so that we know later on that if self has this value
// then it is properly initialized.
@@ -209,6 +206,9 @@
return;
}
+ CallOrObjCMessage MsgWrapper(msg, C.getState(), C.getLocationContext());
+ checkPostStmt(MsgWrapper, C);
+
// We don't check for an invalid 'self' in an obj-c message expression to cut
// down false positives where logging functions get information from self
// (like its class) or doing "invalidation" on self when the initialization
@@ -277,6 +277,11 @@
CheckerContext &C) const {
ProgramStateRef state = C.getState();
unsigned NumArgs = CE.getNumArgs();
+ // If we passed 'self' as and argument to the call, record it in the state
+ // to be propagated after the call.
+ // Note, we could have just given up, but try to be more optimistic here and
+ // assume that the functions are going to continue initialization or will not
+ // modify self.
for (unsigned i = 0; i < NumArgs; ++i) {
SVal argV = CE.getArgSVal(i);
if (isSelfVar(argV, C)) {
@@ -298,14 +303,24 @@
for (unsigned i = 0; i < NumArgs; ++i) {
SVal argV = CE.getArgSVal(i);
if (isSelfVar(argV, C)) {
+ // If the address of 'self' is being passed to the call, assume that the
+ // 'self' after the call will have the same flags.
+ // EX: log(&self)
SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
state = state->remove<PreCallSelfFlags>();
addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C);
return;
} else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
+ // If 'self' is passed to the call by value, assume that the function
+ // returns 'self'. So assign the flags, which were set on 'self' to the
+ // return value.
+ // EX: self = performMoreInitialization(self)
SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
state = state->remove<PreCallSelfFlags>();
- addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C);
+ const Expr *CallExpr = CE.getOriginExpr();
+ if (CallExpr)
+ addSelfFlag(state, state->getSVal(CallExpr, C.getLocationContext()),
+ prevFlags, C);
return;
}
}
@@ -358,7 +373,7 @@
return false;
loc::MemRegionVal MRV = cast<loc::MemRegionVal>(location);
- if (const DeclRegion *DR = dyn_cast<DeclRegion>(MRV.getRegion()))
+ if (const DeclRegion *DR = dyn_cast<DeclRegion>(MRV.stripCasts()))
return (DR->getDecl() == analCtx->getSelfDecl());
return false;
Modified: cfe/trunk/test/Analysis/self-init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/self-init.m?rev=154866&r1=154865&r2=154866&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/self-init.m (original)
+++ cfe/trunk/test/Analysis/self-init.m Mon Apr 16 16:51:09 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties %s -verify
@class NSZone, NSCoder;
@protocol NSObject- (id)self;
@@ -48,9 +48,7 @@
extern void *somePtr;
@class MyObj;
-static id _commonInit(MyObj *self) {
- return self;
-}
+extern id _commonInit(MyObj *self);
@interface MyObj : NSObject {
id myivar;
@@ -59,6 +57,7 @@
-(id)_init;
-(id)initWithSomething:(int)x;
-(void)doSomething;
++(id)commonInitMember:(id)s;
@end
@interface MyProxyObj : NSProxy {}
@@ -90,6 +89,14 @@
return self;
}
+-(id)init4_w {
+ [super init];
+ if (self) {
+ log(&self);
+ }
+ return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self) init...]'}}
+}
+
- (id)initWithSomething:(int)x {
if ((self = [super init]))
myint = x;
@@ -157,6 +164,12 @@
return self;
}
+-(id)init14_w {
+ [super init];
+ self = _commonInit(self);
+ return self; // expected-warning {{Returning 'self' while it is not set to the result of '[(super or self) init...]'}}
+}
+
-(id)init15 {
if (!(self = [super init]))
return 0;
@@ -176,6 +189,28 @@
return 0;
}
+-(id)init18 {
+ self = [super init];
+ self = _commonInit(self);
+ return self;
+}
+
++(id)commonInitMember:(id)s {
+ return s;
+}
+
+-(id)init19 {
+ self = [super init];
+ self = [MyObj commonInitMember:self];
+ return self;
+}
+
+-(id)init19_w {
+ [super init];
+ self = [MyObj commonInitMember:self];
+ return self; // expected-warning {{Returning 'self'}}
+}
+
-(void)doSomething {}
@end
@@ -201,3 +236,21 @@
}
@end
+// Test radar:11235991 - passing self to a call to super.
+ at protocol MyDelegate
+ at end
+ at interface Object : NSObject
+- (id) initWithObject: (id)i;
+ at end
+ at interface Derived: Object <MyDelegate>
+- (id) initWithInt: (int)t;
+ at property (nonatomic, retain, readwrite) Object *size;
+ at end
+ at implementation Derived
+- (id) initWithInt: (int)t {
+ if ((self = [super initWithObject:self])) {
+ _size = [[Object alloc] init];
+ }
+ return self;
+}
+ at end
More information about the cfe-commits
mailing list