[cfe-commits] r156420 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp test/Analysis/self-init.m

Anna Zaks ganna at apple.com
Tue May 8 14:19:21 PDT 2012


Author: zaks
Date: Tue May  8 16:19:21 2012
New Revision: 156420

URL: http://llvm.org/viewvc/llvm-project?rev=156420&view=rev
Log:
[analyzer] SelfInit: Stop tracking self if it's assigned a value we
don't reason about.

Self is just like a local variable in init methods, so it can be
assigned anything like result of static functions, other methods ... So
to suppress false positives that result in such cases, stop tracking the
checker-specific state after self is being assigned to (unless the
value is't being assigned to is either self or conforms to our rules).

This change does not invalidate any existing regression 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=156420&r1=156419&r2=156420&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp Tue May  8 16:19:21 2012
@@ -60,7 +60,8 @@
                                              check::PreStmt<ReturnStmt>,
                                              check::PreStmt<CallExpr>,
                                              check::PostStmt<CallExpr>,
-                                             check::Location > {
+                                             check::Location,
+                                             check::Bind > {
 public:
   void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
   void checkPostObjCMessage(ObjCMessage msg, CheckerContext &C) const;
@@ -70,6 +71,7 @@
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
   void checkLocation(SVal location, bool isLoad, const Stmt *S,
                      CheckerContext &C) const;
+  void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
 
   void checkPreStmt(const CallOrObjCMessage &CE, CheckerContext &C) const;
   void checkPostStmt(const CallOrObjCMessage &CE, CheckerContext &C) const;
@@ -336,6 +338,28 @@
     addSelfFlag(state, state->getSVal(cast<Loc>(location)), SelfFlag_Self, C);
 }
 
+
+void ObjCSelfInitChecker::checkBind(SVal loc, SVal val, const Stmt *S,
+                                    CheckerContext &C) const {
+  // Allow assignment of anything to self. Self is a local variable in the
+  // initializer, so it is legal to assign anything to it, like results of
+  // static functions/method calls. After self is assigned something we cannot 
+  // reason about, stop enforcing the rules.
+  // (Only continue checking if the assigned value should be treated as self.)
+  if ((isSelfVar(loc, C)) &&
+      !hasSelfFlag(val, SelfFlag_InitRes, C) &&
+      !hasSelfFlag(val, SelfFlag_Self, C) &&
+      !isSelfVar(val, C)) {
+
+    // Stop tracking the checker-specific state in the state.
+    ProgramStateRef State = C.getState();
+    State = State->remove<CalledInit>();
+    if (SymbolRef sym = loc.getAsSymbol())
+      State = State->remove<SelfFlag>(sym);
+    C.addTransition(State);
+  }
+}
+
 // FIXME: A callback should disable checkers at the start of functions.
 static bool shouldRunOnFunctionOrMethod(const NamedDecl *ND) {
   if (!ND)

Modified: cfe/trunk/test/Analysis/self-init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/self-init.m?rev=156420&r1=156419&r2=156420&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/self-init.m (original)
+++ cfe/trunk/test/Analysis/self-init.m Tue May  8 16:19:21 2012
@@ -1,7 +1,8 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -fno-builtin %s -verify
 
 @class NSZone, NSCoder;
- at protocol NSObject- (id)self;
+ at protocol NSObject
+- (id)self;
 @end
 @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
 @end 
@@ -254,3 +255,28 @@
    return self;
 }
 @end
+
+// Test for radar://11125870: init constructing a special instance.
+typedef signed char BOOL;
+ at interface MyClass : NSObject
+ at end
+ at implementation MyClass
++ (id)specialInstance {
+    return [[MyClass alloc] init];
+}
+- (id)initSpecially:(BOOL)handleSpecially {
+    if ((self = [super init])) {
+        if (handleSpecially) {
+            self = [MyClass specialInstance];
+        }
+    }
+    return self;
+}
+- (id)initSelfSelf {
+    if ((self = [super init])) {
+      self = self;
+    }
+    return self;
+}
+ at end
+





More information about the cfe-commits mailing list