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

Anna Zaks ganna at apple.com
Mon Mar 5 10:58:25 PST 2012


Author: zaks
Date: Mon Mar  5 12:58:25 2012
New Revision: 152039

URL: http://llvm.org/viewvc/llvm-project?rev=152039&view=rev
Log:
[analyzer] False positive in SelfInit - teach the checker about method
calls with self as a parameter.

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=152039&r1=152038&r2=152039&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp Mon Mar  5 12:58:25 2012
@@ -54,7 +54,7 @@
 static bool isSelfVar(SVal location, CheckerContext &C);
 
 namespace {
-class ObjCSelfInitChecker : public Checker<
+class ObjCSelfInitChecker : public Checker<  check::PreObjCMessage,
                                              check::PostObjCMessage,
                                              check::PostStmt<ObjCIvarRefExpr>,
                                              check::PreStmt<ReturnStmt>,
@@ -62,6 +62,7 @@
                                              check::PostStmt<CallExpr>,
                                              check::Location > {
 public:
+  void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
   void checkPostObjCMessage(ObjCMessage msg, CheckerContext &C) const;
   void checkPostStmt(const ObjCIvarRefExpr *E, CheckerContext &C) const;
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
@@ -69,6 +70,10 @@
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
   void checkLocation(SVal location, bool isLoad, const Stmt *S,
                      CheckerContext &C) const;
+
+  void checkPreStmt(const CallOrObjCMessage &CE, CheckerContext &C) const;
+  void checkPostStmt(const CallOrObjCMessage &CE, CheckerContext &C) const;
+
 };
 } // end anonymous namespace
 
@@ -178,6 +183,9 @@
 
 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.
@@ -249,10 +257,28 @@
 
 void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
                                        CheckerContext &C) const {
+  CallOrObjCMessage CEWrapper(CE, C.getState(), C.getLocationContext());
+  checkPreStmt(CEWrapper, C);
+}
+
+void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
+                                        CheckerContext &C) const {
+  CallOrObjCMessage CEWrapper(CE, C.getState(), C.getLocationContext());
+  checkPostStmt(CEWrapper, C);
+}
+
+void ObjCSelfInitChecker::checkPreObjCMessage(ObjCMessage Msg,
+                                              CheckerContext &C) const {
+  CallOrObjCMessage MsgWrapper(Msg, C.getState(), C.getLocationContext());
+  checkPreStmt(MsgWrapper, C);
+}
+
+void ObjCSelfInitChecker::checkPreStmt(const CallOrObjCMessage &CE,
+                                       CheckerContext &C) const {
   ProgramStateRef state = C.getState();
-  for (CallExpr::const_arg_iterator
-         I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
-    SVal argV = state->getSVal(*I, C.getLocationContext());
+  unsigned NumArgs = CE.getNumArgs();
+  for (unsigned i = 0; i < NumArgs; ++i) {
+    SVal argV = CE.getArgSVal(i);
     if (isSelfVar(argV, C)) {
       unsigned selfFlags = getSelfFlags(state->getSVal(cast<Loc>(argV)), C);
       C.addTransition(state->set<PreCallSelfFlags>(selfFlags));
@@ -265,13 +291,12 @@
   }
 }
 
-void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
+void ObjCSelfInitChecker::checkPostStmt(const CallOrObjCMessage &CE,
                                         CheckerContext &C) const {
   ProgramStateRef state = C.getState();
-  const LocationContext *LCtx = C.getLocationContext();
-  for (CallExpr::const_arg_iterator
-         I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
-    SVal argV = state->getSVal(*I, LCtx);
+  unsigned NumArgs = CE.getNumArgs();
+  for (unsigned i = 0; i < NumArgs; ++i) {
+    SVal argV = CE.getArgSVal(i);
     if (isSelfVar(argV, C)) {
       SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
       state = state->remove<PreCallSelfFlags>();
@@ -280,7 +305,7 @@
     } else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
       SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
       state = state->remove<PreCallSelfFlags>();
-      addSelfFlag(state, state->getSVal(CE, LCtx), prevFlags, C);
+      addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C);
       return;
     }
   }

Modified: cfe/trunk/test/Analysis/self-init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/self-init.m?rev=152039&r1=152038&r2=152039&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/self-init.m (original)
+++ cfe/trunk/test/Analysis/self-init.m Mon Mar  5 12:58:25 2012
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit %s -verify
 
 @class NSZone, NSCoder;
- at protocol NSObject
- at end 
+ at protocol NSObject- (id)self;
+ at end
 @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
 @end 
 @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
@@ -22,9 +22,14 @@
 
 //#import "Foundation/NSObject.h"
 typedef unsigned NSUInteger;
-typedef int NSInteger;
+typedef long NSInteger;
+
+ at interface NSInvocation : NSObject {}
+- (void)getArgument:(void *)argumentLocation atIndex:(NSInteger)idx;
+- (void)setArgument:(void *)argumentLocation atIndex:(NSInteger)idx;
+ at end
 
- at class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+ at class NSMethodSignature, NSCoder, NSString, NSEnumerator;
 @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
 - (NSUInteger)length;
 + (id)stringWithUTF8String:(const char *)nullTerminatedCString;
@@ -180,3 +185,19 @@
 - (id)init { return self; }
 
 @end
+
+
+// Test for radar://10973514 : self should not be invalidated by a method call.
+ at interface Test : NSObject {
+    NSInvocation *invocation_;
+}
+ at end
+ at implementation Test
+-(id) initWithTarget:(id) rec selector:(SEL) cb {
+  if (self=[super init]) {
+    [invocation_ setArgument:&self atIndex:2];
+  }   
+  return self;
+}
+ at end
+





More information about the cfe-commits mailing list