aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-12-13 00:42:19 +0000
committerAnna Zaks <ganna@apple.com>2012-12-13 00:42:19 +0000
commit1812652c24c5a7847654cef9b0875414000af27f (patch)
treed5c324762728b3c25e110464d447eee1c23a12e2
parent0c252fa8b751be50f8b53ffdc6563dca609870fc (diff)
[analyzer] Fix a self-init checker false positive.
This is a Band-Aid fix to a false positive, where we complain about not initializing self to [super init], where self is not coming from the init method, but is coming from the caller to init. The proper solution would be to associate the self and it's state with the enclosing init. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170059 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp9
-rw-r--r--test/Analysis/self-init.m25
2 files changed, 32 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index 713459fdab..485ae77242 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
@@ -123,9 +123,10 @@ static SelfFlagEnum getSelfFlags(SVal val, CheckerContext &C) {
static void addSelfFlag(ProgramStateRef state, SVal val,
SelfFlagEnum flag, CheckerContext &C) {
// We tag the symbol that the SVal wraps.
- if (SymbolRef sym = val.getAsSymbol())
+ if (SymbolRef sym = val.getAsSymbol()) {
state = state->set<SelfFlag>(sym, getSelfFlags(val, state) | flag);
- C.addTransition(state);
+ C.addTransition(state);
+ }
}
static bool hasSelfFlag(SVal val, SelfFlagEnum flag, CheckerContext &C) {
@@ -303,6 +304,10 @@ void ObjCSelfInitChecker::checkPostCall(const CallEvent &CE,
void ObjCSelfInitChecker::checkLocation(SVal location, bool isLoad,
const Stmt *S,
CheckerContext &C) const {
+ if (!shouldRunOnFunctionOrMethod(dyn_cast<NamedDecl>(
+ C.getCurrentAnalysisDeclContext()->getDecl())))
+ return;
+
// Tag the result of a load from 'self' so that we can easily know that the
// value is the object that 'self' points to.
ProgramStateRef state = C.getState();
diff --git a/test/Analysis/self-init.m b/test/Analysis/self-init.m
index b0c51a2b37..d8e8888287 100644
--- a/test/Analysis/self-init.m
+++ b/test/Analysis/self-init.m
@@ -281,3 +281,28 @@ typedef signed char BOOL;
}
@end
+// Test for radar://12838705.
+@interface ABCClass : NSObject
+@property (nonatomic, strong) NSString *foo;
+@property (nonatomic, strong) NSString *bar;
+@property (nonatomic, strong) NSString *baz;
+@end
+
+@implementation ABCClass
+@synthesize foo = foo_;
+@synthesize bar = bar_;
+@synthesize baz = baz_;
+
+- (id)initWithABC:(ABCClass *)abc {
+ self = [super init];
+ baz_ = abc->baz_;
+ return self;
+}
+
+- (ABCClass *)abcWithFoo:(NSString *)foo {
+ ABCClass *copy = [[ABCClass alloc] initWithABC:self];
+ return copy;
+}
+
+@end
+