[cfe-commits] r130711 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/StaticAnalyzer/Checkers/ lib/StaticAnalyzer/Core/ test/Analysis/

Ted Kremenek kremenek at apple.com
Mon May 2 12:42:43 PDT 2011


Author: kremenek
Date: Mon May  2 14:42:42 2011
New Revision: 130711

URL: http://llvm.org/viewvc/llvm-project?rev=130711&view=rev
Log:
Augment retain/release checker to not warn about tracked objects passed as arguments to C++ constructors.  This is a stop-gap measure for Objective-C++ code that uses smart pointers to manage reference counts.

Added:
    cfe/trunk/test/Analysis/retain-release.mm
Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
    cfe/trunk/test/Analysis/retain-release.m

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Mon May  2 14:42:42 2011
@@ -240,9 +240,11 @@
 class RegionChanges {
   template <typename CHECKER>
   static const GRState *_checkRegionChanges(void *checker, const GRState *state,
+                            const StoreManager::InvalidatedSymbols *invalidated,
                                             const MemRegion * const *Begin,
                                             const MemRegion * const *End) {
-    return ((const CHECKER *)checker)->checkRegionChanges(state, Begin, End);
+    return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
+                                                          Begin, End);
   }
   template <typename CHECKER>
   static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) {

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Mon May  2 14:42:42 2011
@@ -18,6 +18,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
 #include <vector>
 
 namespace clang {
@@ -49,6 +50,18 @@
 
 template <typename T> class CheckerFn;
 
+template <typename RET, typename P1, typename P2, typename P3, typename P4>
+class CheckerFn<RET(P1, P2, P3, P4)> {
+  typedef RET (*Func)(void *, P1, P2, P3, P4);
+  Func Fn;
+public:
+  void *Checker;
+  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
+  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { 
+    return Fn(Checker, p1, p2, p3, p4);
+  } 
+};
+
 template <typename RET, typename P1, typename P2, typename P3>
 class CheckerFn<RET(P1, P2, P3)> {
   typedef RET (*Func)(void *, P1, P2, P3);
@@ -224,9 +237,11 @@
   bool wantsRegionChangeUpdate(const GRState *state);
 
   /// \brief Run checkers for region changes.
-  const GRState *runCheckersForRegionChanges(const GRState *state,
-                                             const MemRegion * const *Begin,
-                                             const MemRegion * const *End);
+  const GRState *
+  runCheckersForRegionChanges(const GRState *state,
+                            const StoreManager::InvalidatedSymbols *invalidated,
+                              const MemRegion * const *Begin,
+                              const MemRegion * const *End);
 
   /// \brief Run checkers for handling assumptions on symbolic values.
   const GRState *runCheckersForEvalAssume(const GRState *state,
@@ -283,6 +298,7 @@
   typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc;
   
   typedef CheckerFn<const GRState * (const GRState *,
+                                const StoreManager::InvalidatedSymbols *symbols,
                                      const MemRegion * const *begin,
                                      const MemRegion * const *end)>
       CheckRegionChangesFunc;

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Mon May  2 14:42:42 2011
@@ -188,9 +188,11 @@
 
   /// processRegionChanges - Called by GRStateManager whenever a change is made
   ///  to the store. Used to update checkers that track region values.
-  const GRState* processRegionChanges(const GRState *state,
-                                      const MemRegion * const *Begin,
-                                      const MemRegion * const *End);
+  const GRState *
+  processRegionChanges(const GRState *state,
+                       const StoreManager::InvalidatedSymbols *invalidated,
+                       const MemRegion * const *Begin,
+                       const MemRegion * const *End);
 
   virtual GRStateManager& getStateManager() { return StateMgr; }
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h Mon May  2 14:42:42 2011
@@ -368,6 +368,12 @@
     assert(refCount > 0);
     --refCount;
   }
+  
+  const GRState *invalidateRegionsImpl(const MemRegion * const *Begin,
+                                       const MemRegion * const *End,
+                                       const Expr *E, unsigned BlockCount,
+                                       StoreManager::InvalidatedSymbols &IS,
+                                       bool invalidateGlobals) const;
 };
 
 class GRStateSet {

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Mon May  2 14:42:42 2011
@@ -188,7 +188,7 @@
                                      const MemRegion * const *Begin,
                                      const MemRegion * const *End,
                                      const Expr *E, unsigned Count,
-                                     InvalidatedSymbols *IS,
+                                     InvalidatedSymbols &IS,
                                      bool invalidateGlobals,
                                      InvalidatedRegions *Regions) = 0;
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Mon May  2 14:42:42 2011
@@ -15,6 +15,7 @@
 
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
 
 namespace clang {
 
@@ -95,13 +96,17 @@
 
   /// processRegionChanges - Called by GRStateManager whenever a change is made
   ///  to the store. Used to update checkers that track region values.
-  virtual const GRState* processRegionChanges(const GRState* state,
-                                              const MemRegion* const *Begin,
-                                              const MemRegion* const *End) = 0;
-
-  inline const GRState* processRegionChange(const GRState* state,
-                                            const MemRegion* MR) {
-    return processRegionChanges(state, &MR, &MR+1);
+  virtual const GRState *
+  processRegionChanges(const GRState *state,
+                       const StoreManager::InvalidatedSymbols *invalidated,
+                       const MemRegion* const *Begin,
+                       const MemRegion* const *End) = 0;
+
+
+  inline const GRState *
+  processRegionChange(const GRState* state,
+                      const MemRegion* MR) {
+    return processRegionChanges(state, 0, &MR, &MR+1);
   }
 
   /// Called by CoreEngine when the analysis worklist is either empty or the

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Mon May  2 14:42:42 2011
@@ -42,6 +42,7 @@
   bool wantsRegionChangeUpdate(const GRState *state) const;
 
   const GRState *checkRegionChanges(const GRState *state,
+                                    const StoreManager::InvalidatedSymbols *,
                                     const MemRegion * const *Begin,
                                     const MemRegion * const *End) const;
 
@@ -1305,6 +1306,7 @@
 
 const GRState *
 CStringChecker::checkRegionChanges(const GRState *state,
+                                   const StoreManager::InvalidatedSymbols *,
                                    const MemRegion * const *Begin,
                                    const MemRegion * const *End) const {
   CStringLength::EntryMap Entries = state->get<CStringLength>();

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp Mon May  2 14:42:42 2011
@@ -49,11 +49,11 @@
   SVal Retrieve(Store store, Loc loc, QualType T = QualType());
 
   StoreRef invalidateRegion(Store store, const MemRegion *R, const Expr *E,
-                            unsigned Count, InvalidatedSymbols *IS);
+                            unsigned Count, InvalidatedSymbols &IS);
 
   StoreRef invalidateRegions(Store store, const MemRegion * const *Begin,
                              const MemRegion * const *End, const Expr *E,
-                             unsigned Count, InvalidatedSymbols *IS,
+                             unsigned Count, InvalidatedSymbols &IS,
                              bool invalidateGlobals,
                              InvalidatedRegions *Regions);
 
@@ -538,7 +538,7 @@
                                               const MemRegion * const *I,
                                               const MemRegion * const *End,
                                               const Expr *E, unsigned Count,
-                                              InvalidatedSymbols *IS,
+                                              InvalidatedSymbols &IS,
                                               bool invalidateGlobals,
                                               InvalidatedRegions *Regions) {
   StoreRef newStore(store, *this);
@@ -587,18 +587,16 @@
                                              const MemRegion *R,
                                              const Expr *E,
                                              unsigned Count,
-                                             InvalidatedSymbols *IS) {
+                                             InvalidatedSymbols &IS) {
   R = R->StripCasts();
 
   if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
       return StoreRef(store, *this);
 
-  if (IS) {
-    BindingsTy B = GetBindings(store);
-    if (BindingsTy::data_type *Val = B.lookup(R)) {
-      if (SymbolRef Sym = Val->getAsSymbol())
-        IS->insert(Sym);
-    }
+  BindingsTy B = GetBindings(store);
+  if (BindingsTy::data_type *Val = B.lookup(R)) {
+    if (SymbolRef Sym = Val->getAsSymbol())
+      IS.insert(Sym);
   }
 
   QualType T = cast<TypedRegion>(R)->getValueType();

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Mon May  2 14:42:42 2011
@@ -2494,6 +2494,23 @@
   return RetTy;
 }
 
+
+// HACK: Symbols that have ref-count state that are referenced directly
+//  (not as structure or array elements, or via bindings) by an argument
+//  should not have their ref-count state stripped after we have
+//  done an invalidation pass.
+//
+// FIXME: This is a global to currently share between CFRefCount and
+// RetainReleaseChecker.  Eventually all functionality in CFRefCount should
+// be migrated to RetainReleaseChecker, and we can make this a non-global.
+llvm::DenseSet<SymbolRef> WhitelistedSymbols;
+namespace {
+struct ResetWhiteList {
+  ResetWhiteList() {}
+  ~ResetWhiteList() { WhitelistedSymbols.clear(); } 
+};
+}
+
 void CFRefCount::evalSummary(ExplodedNodeSet& Dst,
                              ExprEngine& Eng,
                              StmtNodeBuilder& Builder,
@@ -2510,12 +2527,9 @@
   SymbolRef ErrorSym = 0;
 
   llvm::SmallVector<const MemRegion*, 10> RegionsToInvalidate;
-
-  // HACK: Symbols that have ref-count state that are referenced directly
-  //  (not as structure or array elements, or via bindings) by an argument
-  //  should not have their ref-count state stripped after we have
-  //  done an invalidation pass.
-  llvm::DenseSet<SymbolRef> WhitelistedSymbols;
+  
+  // Use RAII to make sure the whitelist is properly cleared.
+  ResetWhiteList resetWhiteList;
 
   // Invalidate all instance variables of the receiver of a message.
   // FIXME: We should be able to do better with inter-procedural analysis.
@@ -2624,21 +2638,13 @@
 
   // NOTE: Even if RegionsToInvalidate is empty, we must still invalidate
   //  global variables.
+  // NOTE: RetainReleaseChecker handles the actual invalidation of symbols.
   state = state->invalidateRegions(RegionsToInvalidate.data(),
                                    RegionsToInvalidate.data() +
                                    RegionsToInvalidate.size(),
                                    Ex, Count, &IS,
                                    /* invalidateGlobals = */ true);
 
-  for (StoreManager::InvalidatedSymbols::iterator I = IS.begin(),
-       E = IS.end(); I!=E; ++I) {
-    SymbolRef sym = *I;
-    if (WhitelistedSymbols.count(sym))
-      continue;
-    // Remove any existing reference-count binding.
-    state = state->remove<RefBindings>(*I);
-  }
-
   // Evaluate the effect on the message receiver.
   if (!ErrorRange.isValid() && Receiver) {
     SymbolRef Sym = Receiver.getSValAsScalarOrLoc(state).getAsLocSymbol();
@@ -3418,12 +3424,43 @@
 
 namespace {
 class RetainReleaseChecker
-  : public Checker< check::PostStmt<BlockExpr> > {
+  : public Checker< check::PostStmt<BlockExpr>, check::RegionChanges > {
 public:
+    bool wantsRegionUpdate;
+    
+    RetainReleaseChecker() : wantsRegionUpdate(true) {}
+    
+    
     void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
+    const GRState *checkRegionChanges(const GRState *state,
+                            const StoreManager::InvalidatedSymbols *invalidated,
+                                      const MemRegion * const *begin,
+                                      const MemRegion * const *end) const;
+                                          
+    bool wantsRegionChangeUpdate(const GRState *state) const {
+      return wantsRegionUpdate;
+    }
 };
 } // end anonymous namespace
 
+const GRState *
+RetainReleaseChecker::checkRegionChanges(const GRState *state,
+                            const StoreManager::InvalidatedSymbols *invalidated,
+                                         const MemRegion * const *begin,
+                                         const MemRegion * const *end) const {
+  if (!invalidated)
+    return state;
+
+  for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(),
+       E = invalidated->end(); I!=E; ++I) {
+    SymbolRef sym = *I;
+    if (WhitelistedSymbols.count(sym))
+      continue;
+    // Remove any existing reference-count binding.
+    state = state->remove<RefBindings>(sym);
+  }
+  return state;
+}
 
 void RetainReleaseChecker::checkPostStmt(const BlockExpr *BE,
                                          CheckerContext &C) const {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Mon May  2 14:42:42 2011
@@ -345,6 +345,7 @@
 /// \brief Run checkers for region changes.
 const GRState *
 CheckerManager::runCheckersForRegionChanges(const GRState *state,
+                            const StoreManager::InvalidatedSymbols *invalidated,
                                             const MemRegion * const *Begin,
                                             const MemRegion * const *End) {
   for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
@@ -352,7 +353,7 @@
     // bail out.
     if (!state)
       return NULL;
-    state = RegionChangesCheckers[i].CheckFn(state, Begin, End);
+    state = RegionChangesCheckers[i].CheckFn(state, invalidated, Begin, End);
   }
   return state;
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon May  2 14:42:42 2011
@@ -179,9 +179,11 @@
 
 const GRState *
 ExprEngine::processRegionChanges(const GRState *state,
-                                   const MemRegion * const *Begin,
-                                   const MemRegion * const *End) {
-  return getCheckerManager().runCheckersForRegionChanges(state, Begin, End);
+                            const StoreManager::InvalidatedSymbols *invalidated,
+                                 const MemRegion * const *Begin,
+                                 const MemRegion * const *End) {
+  return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
+                                                         Begin, End);
 }
 
 void ExprEngine::processEndWorklist(bool hasWorkRemaining) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp Mon May  2 14:42:42 2011
@@ -59,7 +59,7 @@
   
   StoreRef invalidateRegions(Store store, const MemRegion * const *I,
                              const MemRegion * const *E, const Expr *Ex,
-                             unsigned Count, InvalidatedSymbols *IS,
+                             unsigned Count, InvalidatedSymbols &IS,
                              bool invalidateGlobals,
                              InvalidatedRegions *Regions);
 
@@ -175,7 +175,7 @@
                                              const MemRegion * const *I,
                                              const MemRegion * const *E,
                                              const Expr *Ex, unsigned Count,
-                                             InvalidatedSymbols *IS,
+                                             InvalidatedSymbols &IS,
                                              bool invalidateGlobals,
                                              InvalidatedRegions *Regions) {
   assert(false && "Not implemented");

Modified: cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp Mon May  2 14:42:42 2011
@@ -141,6 +141,20 @@
                                           const Expr *E, unsigned Count,
                                           StoreManager::InvalidatedSymbols *IS,
                                           bool invalidateGlobals) const {
+  if (!IS) {
+    StoreManager::InvalidatedSymbols invalidated;
+    return invalidateRegionsImpl(Begin, End, E, Count,
+                             invalidated, invalidateGlobals);
+  }
+  return invalidateRegionsImpl(Begin, End, E, Count, *IS, invalidateGlobals);
+}
+
+const GRState *
+GRState::invalidateRegionsImpl(const MemRegion * const *Begin,
+                               const MemRegion * const *End,
+                               const Expr *E, unsigned Count,
+                               StoreManager::InvalidatedSymbols &IS,
+                               bool invalidateGlobals) const {
   GRStateManager &Mgr = getStateManager();
   SubEngine* Eng = Mgr.getOwningEngine();
  
@@ -150,7 +164,7 @@
       = Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS,
                                         invalidateGlobals, &Regions);
     const GRState *newState = makeWithStore(newStore);
-    return Eng->processRegionChanges(newState,
+    return Eng->processRegionChanges(newState, &IS,
                                      &Regions.front(),
                                      &Regions.back()+1);
   }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Mon May  2 14:42:42 2011
@@ -240,7 +240,7 @@
                              const MemRegion * const *Begin,
                              const MemRegion * const *End,
                              const Expr *E, unsigned Count,
-                             InvalidatedSymbols *IS,
+                             InvalidatedSymbols &IS,
                              bool invalidateGlobals,
                              InvalidatedRegions *Regions);
 
@@ -586,14 +586,14 @@
 {
   const Expr *Ex;
   unsigned Count;
-  StoreManager::InvalidatedSymbols *IS;
+  StoreManager::InvalidatedSymbols &IS;
   StoreManager::InvalidatedRegions *Regions;
 public:
   invalidateRegionsWorker(RegionStoreManager &rm,
                           GRStateManager &stateMgr,
                           RegionBindings b,
                           const Expr *ex, unsigned count,
-                          StoreManager::InvalidatedSymbols *is,
+                          StoreManager::InvalidatedSymbols &is,
                           StoreManager::InvalidatedRegions *r,
                           bool includeGlobals)
     : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, includeGlobals),
@@ -609,9 +609,8 @@
 
 void invalidateRegionsWorker::VisitBinding(SVal V) {
   // A symbol?  Mark it touched by the invalidation.
-  if (IS)
-    if (SymbolRef Sym = V.getAsSymbol())
-      IS->insert(Sym);
+  if (SymbolRef Sym = V.getAsSymbol())
+    IS.insert(Sym);
 
   if (const MemRegion *R = V.getAsRegion()) {
     AddToWorkList(R);
@@ -648,11 +647,9 @@
 }
 
 void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
-  if (IS) {
-    // Symbolic region?  Mark that symbol touched by the invalidation.
-    if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
-      IS->insert(SR->getSymbol());
-  }
+  // Symbolic region?  Mark that symbol touched by the invalidation.
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
+    IS.insert(SR->getSymbol());
 
   // BlockDataRegion?  If so, invalidate captured variables that are passed
   // by reference.
@@ -724,7 +721,7 @@
                                                const MemRegion * const *I,
                                                const MemRegion * const *E,
                                                const Expr *Ex, unsigned Count,
-                                               InvalidatedSymbols *IS,
+                                               InvalidatedSymbols &IS,
                                                bool invalidateGlobals,
                                                InvalidatedRegions *Regions) {
   invalidateRegionsWorker W(*this, StateMgr,

Modified: cfe/trunk/test/Analysis/retain-release.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.m?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.m (original)
+++ cfe/trunk/test/Analysis/retain-release.m Mon May  2 14:42:42 2011
@@ -280,7 +280,7 @@
   CFRelease(date);
   CFDateGetAbsoluteTime(date); // no-warning
   CFRelease(date);
-  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
+  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released}}
   return t;
 }
 
@@ -291,7 +291,7 @@
   CFRelease(date);
   CFDateGetAbsoluteTime(date); // no-warning
   [((NSDate*) date) release];
-  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released.}}
+  t = CFDateGetAbsoluteTime(date);   // expected-warning{{Reference-counted object is used after it is released}}
   return t;
 }
 

Added: cfe/trunk/test/Analysis/retain-release.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.mm?rev=130711&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.mm (added)
+++ cfe/trunk/test/Analysis/retain-release.mm Mon May  2 14:42:42 2011
@@ -0,0 +1,284 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify %s
+
+#if __has_feature(attribute_ns_returns_retained)
+#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
+#endif
+#if __has_feature(attribute_cf_returns_retained)
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#endif
+#if __has_feature(attribute_ns_returns_not_retained)
+#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+#endif
+#if __has_feature(attribute_cf_returns_not_retained)
+#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#endif
+#if __has_feature(attribute_ns_consumes_self)
+#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
+#endif
+#if __has_feature(attribute_ns_consumed)
+#define NS_CONSUMED __attribute__((ns_consumed))
+#endif
+#if __has_feature(attribute_cf_consumed)
+#define CF_CONSUMED __attribute__((cf_consumed))
+#endif
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from Mac OS X headers:
+//
+// #include <Cocoa/Cocoa.h>
+// #include <CoreFoundation/CoreFoundation.h>
+// #include <DiskArbitration/DiskArbitration.h>
+// #include <QuartzCore/QuartzCore.h>
+// #include <Quartz/Quartz.h>
+// #include <IOKit/IOKitLib.h>
+//
+// It includes the basic definitions for the test cases below.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+typedef unsigned long uintptr_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+typedef unsigned int UInt32;
+typedef signed long CFIndex;
+typedef struct {
+    CFIndex location;
+    CFIndex length;
+} CFRange;
+static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) {
+    CFRange range;
+    range.location = loc;
+    range.length = len;
+    return range;
+}
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+typedef struct __CFArray * CFMutableArrayRef;
+extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
+typedef struct {
+}
+CFDictionaryKeyCallBacks;
+extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+typedef struct {
+}
+CFDictionaryValueCallBacks;
+extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef struct __CFDictionary * CFMutableDictionaryRef;
+extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
+typedef UInt32 CFStringEncoding;
+enum {
+kCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
+typedef __darwin_natural_t natural_t;
+typedef natural_t mach_port_name_t;
+typedef mach_port_name_t mach_port_t;
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+enum {
+kCFNumberSInt8Type = 1,     kCFNumberSInt16Type = 2,     kCFNumberSInt32Type = 3,     kCFNumberSInt64Type = 4,     kCFNumberFloat32Type = 5,     kCFNumberFloat64Type = 6,      kCFNumberCharType = 7,     kCFNumberShortType = 8,     kCFNumberIntType = 9,     kCFNumberLongType = 10,     kCFNumberLongLongType = 11,     kCFNumberFloatType = 12,     kCFNumberDoubleType = 13,      kCFNumberCFIndexType = 14,      kCFNumberNSIntegerType = 15,     kCFNumberCGFloatType = 16,     kCFNumberMaxType = 16    };
+typedef CFIndex CFNumberType;
+typedef const struct __CFNumber * CFNumberRef;
+extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+typedef const struct __CFAttributedString *CFAttributedStringRef;
+typedef struct __CFAttributedString *CFMutableAttributedStringRef;
+extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ;
+extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ;
+extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ;
+typedef signed char BOOL;
+typedef unsigned long NSUInteger;
+ at class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef struct _NSZone NSZone;
+ at class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+ at protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+- (id)autorelease;
+ at end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
+ at end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
+ at end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
+ at end
+ at interface NSObject <NSObject> {}
++ (id)allocWithZone:(NSZone *)zone;
++ (id)alloc;
+- (void)dealloc;
+ at end
+ at interface NSObject (NSCoderMethods)
+- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
+ at end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+typedef struct {
+}
+NSFastEnumerationState;
+ at protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+ at end           @class NSString, NSDictionary;
+ at interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
+ at end  @interface NSNumber : NSValue  - (char)charValue;
+- (id)initWithInt:(int)value;
+ at end   @class NSString;
+ at interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+ at end  @interface NSArray (NSArrayCreation)  + (id)array;
+ at end       @interface NSAutoreleasePool : NSObject {
+}
+- (void)drain;
+ at end extern NSString * const NSBundleDidLoadNotification;
+typedef double NSTimeInterval;
+ at interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate;
+ at end            typedef unsigned short unichar;
+ at interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
+- ( const char *)UTF8String;
+- (id)initWithUTF8String:(const char *)nullTerminatedCString;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+ at end        @class NSString, NSURL, NSError;
+ at interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding>  - (NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
+ at end   @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
+ at interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
+ at end    @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey;
+- (void)setObject:(id)anObject forKey:(id)aKey;
+ at end  @interface NSMutableDictionary (NSMutableDictionaryCreation)  + (id)dictionaryWithCapacity:(NSUInteger)numItems;
+ at end  typedef double CGFloat;
+struct CGSize {
+};
+typedef struct CGSize CGSize;
+struct CGRect {
+};
+typedef struct CGRect CGRect;
+typedef mach_port_t io_object_t;
+typedef char io_name_t[128];
+typedef io_object_t io_iterator_t;
+typedef io_object_t io_service_t;
+typedef struct IONotificationPort * IONotificationPortRef;
+typedef void (*IOServiceMatchingCallback)(  void * refcon,  io_iterator_t iterator );
+io_service_t IOServiceGetMatchingService(  mach_port_t masterPort,  CFDictionaryRef matching );
+kern_return_t IOServiceGetMatchingServices(  mach_port_t masterPort,  CFDictionaryRef matching,  io_iterator_t * existing );
+kern_return_t IOServiceAddNotification(  mach_port_t masterPort,  const io_name_t notificationType,  CFDictionaryRef matching,  mach_port_t wakePort,  uintptr_t reference,  io_iterator_t * notification ) __attribute__((deprecated));
+kern_return_t IOServiceAddMatchingNotification(  IONotificationPortRef notifyPort,  const io_name_t notificationType,  CFDictionaryRef matching,         IOServiceMatchingCallback callback,         void * refCon,  io_iterator_t * notification );
+CFMutableDictionaryRef IOServiceMatching(  const char * name );
+CFMutableDictionaryRef IOServiceNameMatching(  const char * name );
+CFMutableDictionaryRef IOBSDNameMatching(  mach_port_t masterPort,  uint32_t options,  const char * bsdName );
+CFMutableDictionaryRef IOOpenFirmwarePathMatching(  mach_port_t masterPort,  uint32_t options,  const char * path );
+CFMutableDictionaryRef IORegistryEntryIDMatching(  uint64_t entryID );
+typedef struct __DASession * DASessionRef;
+extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
+typedef struct __DADisk * DADiskRef;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
+extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
+extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+ at interface NSTask : NSObject - (id)init;
+ at end                    typedef struct CGColorSpace *CGColorSpaceRef;
+typedef struct CGImage *CGImageRef;
+typedef struct CGLayer *CGLayerRef;
+ at interface NSResponder : NSObject <NSCoding> {
+}
+ at end    @protocol NSAnimatablePropertyContainer      - (id)animator;
+ at end  extern NSString *NSAnimationTriggerOrderIn ;
+ at interface NSView : NSResponder  <NSAnimatablePropertyContainer>  {
+}
+ at end @protocol NSValidatedUserInterfaceItem - (SEL)action;
+ at end   @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
+ at end  @class NSDate, NSDictionary, NSError, NSException, NSNotification;
+ at interface NSApplication : NSResponder <NSUserInterfaceValidations> {
+}
+ at end   enum {
+NSTerminateCancel = 0,         NSTerminateNow = 1,         NSTerminateLater = 2 };
+typedef NSUInteger NSApplicationTerminateReply;
+ at protocol NSApplicationDelegate <NSObject> @optional        - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+ at end  @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView;
+ at interface NSCell : NSObject <NSCopying, NSCoding> {
+}
+ at end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+typedef struct {
+}
+CVTimeStamp;
+ at interface CIImage : NSObject <NSCoding, NSCopying> {
+}
+typedef int CIFormat;
+ at end  enum {
+kDAReturnSuccess = 0,     kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
+typedef mach_error_t DAReturn;
+typedef const struct __DADissenter * DADissenterRef;
+extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
+ at interface CIContext: NSObject {
+}
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r     format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
+- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
+ at end extern NSString* const QCRendererEventKey;
+ at protocol QCCompositionRenderer - (NSDictionary*) attributes;
+ at end   @interface QCRenderer : NSObject <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+ at end  extern NSString* const QCViewDidStartRenderingNotification;
+ at interface QCView : NSView <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+ at end    enum {
+ICEXIFOrientation1 = 1,     ICEXIFOrientation2 = 2,     ICEXIFOrientation3 = 3,     ICEXIFOrientation4 = 4,     ICEXIFOrientation5 = 5,     ICEXIFOrientation6 = 6,     ICEXIFOrientation7 = 7,     ICEXIFOrientation8 = 8, };
+ at class ICDevice;
+ at protocol ICDeviceDelegate <NSObject>  @required      - (void)didRemoveDevice:(ICDevice*)device;
+ at end extern NSString *const ICScannerStatusWarmingUp;
+ at class ICScannerDevice;
+ at protocol ICScannerDeviceDelegate <ICDeviceDelegate>  @optional       - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
+ at end
+
+typedef long unsigned int __darwin_size_t;
+typedef __darwin_size_t size_t;
+typedef unsigned long CFTypeID;
+struct CGPoint {
+  CGFloat x;
+  CGFloat y;
+};
+typedef struct CGPoint CGPoint;
+typedef struct CGGradient *CGGradientRef;
+typedef uint32_t CGGradientDrawingOptions;
+extern CFTypeID CGGradientGetTypeID(void);
+extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef
+  space, const CGFloat components[], const CGFloat locations[], size_t count);
+extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space,
+  CFArrayRef colors, const CGFloat locations[]);
+extern CGGradientRef CGGradientRetain(CGGradientRef gradient);
+extern void CGGradientRelease(CGGradientRef gradient);
+typedef struct CGContext *CGContextRef;
+extern void CGContextDrawLinearGradient(CGContextRef context,
+    CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
+    CGGradientDrawingOptions options);
+extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+class SmartPointer {
+  id x;
+public:
+  SmartPointer(id x) : x(x) {}
+  ~SmartPointer() { [x release]; }
+};
+
+void test_smartpointer_1() {
+  id x = [[NSObject alloc] init];  // no-warning
+  SmartPointer foo(x);
+}
+





More information about the cfe-commits mailing list