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

Jordy Rose jediknil at belkadan.com
Sat Aug 27 15:51:26 PDT 2011


Author: jrose
Date: Sat Aug 27 17:51:26 2011
New Revision: 138716

URL: http://llvm.org/viewvc/llvm-project?rev=138716&view=rev
Log:
[analyzer] Change the check::RegionChanges callback to include the regions explicitly requested for invalidation.

Also, allow CallOrObjCMessage to wrap a CXXConstructExpr as well.

Finally, this allows us to remove the clunky whitelisting system from CFRefCount/RetainReleaseChecker. Slight regression due to CXXNewExprs not yet being handled in post-statement callbacks (PR forthcoming).

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/ObjCMessage.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.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/CFRefCount.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp

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=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Sat Aug 27 17:51:26 2011
@@ -262,10 +262,10 @@
   _checkRegionChanges(void *checker,
                       const ProgramState *state,
                       const StoreManager::InvalidatedSymbols *invalidated,
-                      const MemRegion * const *Begin,
-                      const MemRegion * const *End) {
+                      ArrayRef<const MemRegion *> Explicits,
+                      ArrayRef<const MemRegion *> Regions) {
     return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
-                                                          Begin, End);
+                                                          Explicits, Regions);
   }
   template <typename CHECKER>
   static bool _wantsRegionChangeUpdate(void *checker,

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=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Sat Aug 27 17:51:26 2011
@@ -238,11 +238,19 @@
   bool wantsRegionChangeUpdate(const ProgramState *state);
 
   /// \brief Run checkers for region changes.
+  ///
+  /// This corresponds to the check::RegionChanges callback.
+  /// \param state The current program state.
+  /// \param invalidated A set of all symbols potentially touched by the change.
+  /// \param ExplicitRegions The regions explicitly requested for invalidation.
+  ///   For example, in the case of a function call, these would be arguments.
+  /// \param Regions The transitive closure of accessible regions,
+  ///   i.e. all regions that may have been touched by this change.
   const ProgramState *
   runCheckersForRegionChanges(const ProgramState *state,
                             const StoreManager::InvalidatedSymbols *invalidated,
-                              const MemRegion * const *Begin,
-                              const MemRegion * const *End);
+                              ArrayRef<const MemRegion *> ExplicitRegions,
+                              ArrayRef<const MemRegion *> Regions);
 
   /// \brief Run checkers for handling assumptions on symbolic values.
   const ProgramState *runCheckersForEvalAssume(const ProgramState *state,
@@ -305,8 +313,8 @@
   
   typedef CheckerFn<const ProgramState * (const ProgramState *,
                                 const StoreManager::InvalidatedSymbols *symbols,
-                                     const MemRegion * const *begin,
-                                     const MemRegion * const *end)>
+                                    ArrayRef<const MemRegion *> ExplicitRegions,
+                                          ArrayRef<const MemRegion *> Regions)>
       CheckRegionChangesFunc;
   
   typedef CheckerFn<bool (const ProgramState *)> WantsRegionChangeUpdateFunc;

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=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Sat Aug 27 17:51:26 2011
@@ -192,8 +192,8 @@
   const ProgramState *
   processRegionChanges(const ProgramState *state,
                        const StoreManager::InvalidatedSymbols *invalidated,
-                       const MemRegion * const *Begin,
-                       const MemRegion * const *End);
+                       ArrayRef<const MemRegion *> ExplicitRegions,
+                       ArrayRef<const MemRegion *> Regions);
 
   virtual ProgramStateManager& getStateManager() { return StateMgr; }
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h?rev=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h Sat Aug 27 17:51:26 2011
@@ -18,6 +18,8 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprCXX.h"
+#include "llvm/ADT/PointerUnion.h"
 
 namespace clang {
 namespace ento {
@@ -165,62 +167,81 @@
   }
 };
 
-/// \brief Common wrapper for a call expression or an ObjC message, mainly to
-/// provide a common interface for handling their arguments.
+/// \brief Common wrapper for a call expression, ObjC message, or C++ 
+/// constructor, mainly to provide a common interface for their arguments.
 class CallOrObjCMessage {
-  const CallExpr *CallE;
+  llvm::PointerUnion<const CallExpr *, const CXXConstructExpr *> CallE;
   ObjCMessage Msg;
   const ProgramState *State;
 public:
   CallOrObjCMessage(const CallExpr *callE, const ProgramState *state)
     : CallE(callE), State(state) {}
+  CallOrObjCMessage(const CXXConstructExpr *consE, const ProgramState *state)
+    : CallE(consE), State(state) {}
   CallOrObjCMessage(const ObjCMessage &msg, const ProgramState *state)
-    : CallE(0), Msg(msg), State(state) {}
+    : CallE((CallExpr *)0), Msg(msg), State(state) {}
 
   QualType getResultType(ASTContext &ctx) const;
   
   bool isFunctionCall() const {
-    return (bool) CallE;
+    return CallE && CallE.is<const CallExpr *>();
   }
-  
+
+  bool isCXXConstructExpr() const {
+    return CallE && CallE.is<const CXXConstructExpr *>();
+  }
+
+  bool isObjCMessage() const {
+    return !CallE;
+  }
+
   bool isCXXCall() const {
-    return CallE && isa<CXXMemberCallExpr>(CallE);
+    const CallExpr *ActualCallE = CallE.dyn_cast<const CallExpr *>();
+    return ActualCallE && isa<CXXMemberCallExpr>(ActualCallE);
   }
 
   const Expr *getOriginExpr() const {
-    if (isFunctionCall())
-      return CallE;
-    return Msg.getOriginExpr();
+    if (!CallE)
+      return Msg.getOriginExpr();
+    if (const CXXConstructExpr *Ctor =
+          CallE.dyn_cast<const CXXConstructExpr *>())
+      return Ctor;
+    return CallE.get<const CallExpr *>();
   }
   
   SVal getFunctionCallee() const;
   SVal getCXXCallee() const;
 
   unsigned getNumArgs() const {
-    if (CallE) return CallE->getNumArgs();
-    return Msg.getNumArgs();
+    if (!CallE)
+      return Msg.getNumArgs();
+    if (const CXXConstructExpr *Ctor =
+          CallE.dyn_cast<const CXXConstructExpr *>())
+      return Ctor->getNumArgs();
+    return CallE.get<const CallExpr *>()->getNumArgs();
   }
 
   SVal getArgSVal(unsigned i) const {
     assert(i < getNumArgs());
-    if (CallE) 
-      return State->getSVal(CallE->getArg(i));
-    return Msg.getArgSVal(i, State);
+    if (!CallE)
+      return Msg.getArgSVal(i, State);
+    return State->getSVal(getArg(i));
   }
 
-  SVal getArgSValAsScalarOrLoc(unsigned i) const;
-
   const Expr *getArg(unsigned i) const {
     assert(i < getNumArgs());
-    if (CallE)
-      return CallE->getArg(i);
-    return Msg.getArgExpr(i);
+    if (!CallE)
+      return Msg.getArgExpr(i);
+    if (const CXXConstructExpr *Ctor =
+          CallE.dyn_cast<const CXXConstructExpr *>())
+      return Ctor->getArg(i);
+    return CallE.get<const CallExpr *>()->getArg(i);
   }
 
   SourceRange getArgSourceRange(unsigned i) const {
     assert(i < getNumArgs());
     if (CallE)
-      return CallE->getArg(i)->getSourceRange();
+      return getArg(i)->getSourceRange();
     return Msg.getArgSourceRange(i);
   }
 };

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Sat Aug 27 17:51:26 2011
@@ -216,23 +216,13 @@
 
   const ProgramState *unbindLoc(Loc LV) const;
 
-  /// invalidateRegion - Returns the state with bindings for the given region
-  ///  cleared from the store. See invalidateRegions.
-  const ProgramState *invalidateRegion(const MemRegion *R,
-                                  const Expr *E, unsigned BlockCount,
-                                  StoreManager::InvalidatedSymbols *IS = NULL)
-                                  const {
-    return invalidateRegions(&R, &R+1, E, BlockCount, IS, false);
-  }
-
   /// invalidateRegions - Returns the state with bindings for the given regions
   ///  cleared from the store. The regions are provided as a continuous array
   ///  from Begin to End. Optionally invalidates global regions as well.
-  const ProgramState *invalidateRegions(const MemRegion * const *Begin,
-                                   const MemRegion * const *End,
+  const ProgramState *invalidateRegions(ArrayRef<const MemRegion *> Regions,
                                    const Expr *E, unsigned BlockCount,
-                                   StoreManager::InvalidatedSymbols *IS,
-                                   bool invalidateGlobals) const;
+                                   StoreManager::InvalidatedSymbols *IS = 0,
+                                   bool invalidateGlobals = false) const;
 
   /// enterStackFrame - Returns the state for entry to the given stack frame,
   ///  preserving the current state.
@@ -368,11 +358,11 @@
     --refCount;
   }
   
-  const ProgramState *invalidateRegionsImpl(const MemRegion * const *Begin,
-                                       const MemRegion * const *End,
-                                       const Expr *E, unsigned BlockCount,
-                                       StoreManager::InvalidatedSymbols &IS,
-                                       bool invalidateGlobals) const;
+  const ProgramState *
+  invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
+                        const Expr *E, unsigned BlockCount,
+                        StoreManager::InvalidatedSymbols &IS,
+                        bool invalidateGlobals) const;
 };
 
 class ProgramStateSet {

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=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Sat Aug 27 17:51:26 2011
@@ -187,12 +187,11 @@
   ///   even if they do not currently have bindings. Pass \c NULL if this
   ///   information will not be used.
   virtual StoreRef invalidateRegions(Store store,
-                                     const MemRegion * const *Begin,
-                                     const MemRegion * const *End,
+                                     ArrayRef<const MemRegion *> Regions,
                                      const Expr *E, unsigned Count,
                                      InvalidatedSymbols &IS,
                                      bool invalidateGlobals,
-                                     InvalidatedRegions *Regions) = 0;
+                                     InvalidatedRegions *Invalidated) = 0;
 
   /// enterStackFrame - Let the StoreManager to do something when execution
   /// engine is about to execute into a callee.

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=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Sat Aug 27 17:51:26 2011
@@ -99,14 +99,14 @@
   virtual const ProgramState *
   processRegionChanges(const ProgramState *state,
                        const StoreManager::InvalidatedSymbols *invalidated,
-                       const MemRegion* const *Begin,
-                       const MemRegion* const *End) = 0;
+                       ArrayRef<const MemRegion *> ExplicitRegions,
+                       ArrayRef<const MemRegion *> Regions) = 0;
 
 
   inline const ProgramState *
   processRegionChange(const ProgramState *state,
                       const MemRegion* MR) {
-    return processRegionChanges(state, 0, &MR, &MR+1);
+    return processRegionChanges(state, 0, MR, MR);
   }
 
   /// 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=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Sat Aug 27 17:51:26 2011
@@ -47,8 +47,8 @@
   const ProgramState *
     checkRegionChanges(const ProgramState *state,
                        const StoreManager::InvalidatedSymbols *,
-                       const MemRegion * const *Begin,
-                       const MemRegion * const *End) const;
+                       ArrayRef<const MemRegion *> ExplicitRegions,
+                       ArrayRef<const MemRegion *> Regions) const;
 
   typedef void (CStringChecker::*FnCheck)(CheckerContext &,
                                           const CallExpr *) const;
@@ -786,7 +786,7 @@
 
     // Invalidate this region.
     unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
-    return state->invalidateRegion(R, E, Count, NULL);
+    return state->invalidateRegions(R, E, Count);
   }
 
   // If we have a non-region value by chance, just remove the binding.
@@ -1757,8 +1757,8 @@
 const ProgramState *
 CStringChecker::checkRegionChanges(const ProgramState *state,
                                    const StoreManager::InvalidatedSymbols *,
-                                   const MemRegion * const *Begin,
-                                   const MemRegion * const *End) const {
+                                   ArrayRef<const MemRegion *> ExplicitRegions,
+                                   ArrayRef<const MemRegion *> Regions) const {
   CStringLength::EntryMap Entries = state->get<CStringLength>();
   if (Entries.isEmpty())
     return state;
@@ -1767,8 +1767,9 @@
   llvm::SmallPtrSet<const MemRegion *, 32> SuperRegions;
 
   // First build sets for the changed regions and their super-regions.
-  for ( ; Begin != End; ++Begin) {
-    const MemRegion *MR = *Begin;
+  for (ArrayRef<const MemRegion *>::iterator
+       I = Regions.begin(), E = Regions.end(); I != E; ++I) {
+    const MemRegion *MR = *I;
     Invalidated.insert(MR);
 
     SuperRegions.insert(MR);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp?rev=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Sat Aug 27 17:51:26 2011
@@ -2439,23 +2439,6 @@
   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::evalCallOrMessage(ExplodedNodeSet &Dst, ExprEngine &Eng,
                                    StmtNodeBuilder &Builder,
                                    const CallOrObjCMessage &callOrMsg,
@@ -2465,18 +2448,11 @@
                                    const ProgramState *state) {
 
   SmallVector<const MemRegion*, 10> RegionsToInvalidate;
-  
-  // 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.
   if (Receiver) {
     SVal V = Receiver.getSValAsScalarOrLoc(state);
-    if (SymbolRef Sym = V.getAsLocSymbol()) {
-      if (state->get<RefBindings>(Sym))
-        WhitelistedSymbols.insert(Sym);
-    }
     if (const MemRegion *region = V.getAsRegion())
       RegionsToInvalidate.push_back(region);
   }
@@ -2490,7 +2466,7 @@
   }
   
   for (unsigned idx = 0, e = callOrMsg.getNumArgs(); idx != e; ++idx) {
-    SVal V = callOrMsg.getArgSValAsScalarOrLoc(idx);
+    SVal V = callOrMsg.getArgSVal(idx);
 
     // If we are passing a location wrapped as an integer, unwrap it and
     // invalidate the values referred by the location.
@@ -2499,10 +2475,6 @@
     else if (!isa<Loc>(V))
       continue;
 
-    if (SymbolRef Sym = V.getAsLocSymbol())
-      if (state->get<RefBindings>(Sym))
-        WhitelistedSymbols.insert(Sym);
-
     if (const MemRegion *R = V.getAsRegion()) {
       // Invalidate the value of the variable passed by reference.
 
@@ -2562,9 +2534,7 @@
   //  global variables.
   // NOTE: RetainReleaseChecker handles the actual invalidation of symbols.
   state =
-    state->invalidateRegions(RegionsToInvalidate.data(),
-                             RegionsToInvalidate.data() +
-                             RegionsToInvalidate.size(),
+    state->invalidateRegions(RegionsToInvalidate,
                              Ex, Count, &IS,
                              /* invalidateGlobals = */
                              Eng.doesInvalidateGlobals(callOrMsg));
@@ -2611,6 +2581,7 @@
                     check::PostStmt<BlockExpr>,
                     check::PostStmt<CastExpr>,
                     check::PostStmt<CallExpr>,
+                    check::PostStmt<CXXConstructExpr>,
                     check::PostObjCMessage,
                     check::PreStmt<ReturnStmt>,
                     check::RegionChanges,
@@ -2770,6 +2741,7 @@
   void checkPostStmt(const CastExpr *CE, CheckerContext &C) const;
 
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
+  void checkPostStmt(const CXXConstructExpr *CE, CheckerContext &C) const;
   void checkPostObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const;
   void checkSummary(const RetainSummary &Summ, const CallOrObjCMessage &Call,
                     InstanceReceiver Receiver, CheckerContext &C) const;
@@ -2779,10 +2751,11 @@
   const ProgramState *evalAssume(const ProgramState *state, SVal Cond,
                                  bool Assumption) const;
 
-  const ProgramState *checkRegionChanges(const ProgramState *state,
-                          const StoreManager::InvalidatedSymbols *invalidated,
-                                         const MemRegion * const *begin,
-                                         const MemRegion * const *end) const;
+  const ProgramState *
+  checkRegionChanges(const ProgramState *state,
+                     const StoreManager::InvalidatedSymbols *invalidated,
+                     ArrayRef<const MemRegion *> ExplicitRegions,
+                     ArrayRef<const MemRegion *> Regions) const;
                                         
   bool wantsRegionChangeUpdate(const ProgramState *state) const {
     return true;
@@ -2912,11 +2885,18 @@
 const ProgramState *
 RetainReleaseChecker::checkRegionChanges(const ProgramState *state,
                             const StoreManager::InvalidatedSymbols *invalidated,
-                                         const MemRegion * const *begin,
-                                         const MemRegion * const *end) const {
+                                    ArrayRef<const MemRegion *> ExplicitRegions,
+                                    ArrayRef<const MemRegion *> Regions) const {
   if (!invalidated)
     return state;
 
+  llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
+  for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
+       E = ExplicitRegions.end(); I != E; ++I) {
+    if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
+      WhitelistedSymbols.insert(SR->getSymbol());
+  }
+
   for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(),
        E = invalidated->end(); I!=E; ++I) {
     SymbolRef sym = *I;
@@ -3036,6 +3016,23 @@
   checkSummary(*Summ, CallOrObjCMessage(CE, state), InstanceReceiver(), C);
 }
 
+void RetainReleaseChecker::checkPostStmt(const CXXConstructExpr *CE,
+                                         CheckerContext &C) const {
+  const CXXConstructorDecl *Ctor = CE->getConstructor();
+  if (!Ctor)
+    return;
+
+  RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
+  RetainSummary *Summ = Summaries.getSummary(Ctor);
+
+  // If we didn't get a summary, this constructor doesn't affect retain counts.
+  if (!Summ)
+    return;
+
+  const ProgramState *state = C.getState();
+  checkSummary(*Summ, CallOrObjCMessage(CE, state), InstanceReceiver(), C);
+}
+
 void RetainReleaseChecker::checkPostObjCMessage(const ObjCMessage &Msg, 
                                                 CheckerContext &C) const {
   const ProgramState *state = C.getState();
@@ -3071,7 +3068,7 @@
   SymbolRef ErrorSym = 0;
 
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
-    SVal V = CallOrMsg.getArgSValAsScalarOrLoc(idx);
+    SVal V = CallOrMsg.getArgSVal(idx);
 
     if (SymbolRef Sym = V.getAsLocSymbol()) {
       if (RefBindings::data_type *T = state->get<RefBindings>(Sym)) {
@@ -3434,7 +3431,7 @@
 
     // Invalidate the argument region.
     unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
-    state = state->invalidateRegion(ArgRegion, CE, Count);
+    state = state->invalidateRegions(ArgRegion, CE, Count);
 
     // Restore the refcount status of the argument.
     if (Binding)

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Sat Aug 27 17:51:26 2011
@@ -346,14 +346,15 @@
 const ProgramState *
 CheckerManager::runCheckersForRegionChanges(const ProgramState *state,
                             const StoreManager::InvalidatedSymbols *invalidated,
-                                            const MemRegion * const *Begin,
-                                            const MemRegion * const *End) {
+                                    ArrayRef<const MemRegion *> ExplicitRegions,
+                                          ArrayRef<const MemRegion *> Regions) {
   for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
     // If any checker declares the state infeasible (or if it starts that way),
     // bail out.
     if (!state)
       return NULL;
-    state = RegionChangesCheckers[i].CheckFn(state, invalidated, Begin, End);
+    state = RegionChangesCheckers[i].CheckFn(state, invalidated, 
+                                             ExplicitRegions, Regions);
   }
   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=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Sat Aug 27 17:51:26 2011
@@ -192,10 +192,10 @@
 const ProgramState *
 ExprEngine::processRegionChanges(const ProgramState *state,
                             const StoreManager::InvalidatedSymbols *invalidated,
-                                 const MemRegion * const *Begin,
-                                 const MemRegion * const *End) {
+                                 ArrayRef<const MemRegion *> Explicits,
+                                 ArrayRef<const MemRegion *> Regions) {
   return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
-                                                         Begin, End);
+                                                         Explicits, Regions);
 }
 
 void ExprEngine::processEndWorklist(bool hasWorkRemaining) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Sat Aug 27 17:51:26 2011
@@ -229,9 +229,7 @@
     }
     
     // Invalidate the regions.    
-    state = state->invalidateRegions(regionsToInvalidate.data(),
-                                     regionsToInvalidate.data() +
-                                     regionsToInvalidate.size(),
+    state = state->invalidateRegions(regionsToInvalidate,
                                      E, blockCount, 0,
                                      /* invalidateGlobals = */ true);
     
@@ -317,17 +315,13 @@
     if (ObjTy->isRecordType()) {
       regionsToInvalidate.push_back(EleReg);
       // Invalidate the regions.
-      state = state->invalidateRegions(regionsToInvalidate.data(),
-                                       regionsToInvalidate.data() +
-                                       regionsToInvalidate.size(),
+      state = state->invalidateRegions(regionsToInvalidate,
                                        CNE, blockCount, 0,
                                        /* invalidateGlobals = */ true);
       
     } else {
       // Invalidate the regions.
-      state = state->invalidateRegions(regionsToInvalidate.data(),
-                                       regionsToInvalidate.data() +
-                                       regionsToInvalidate.size(),
+      state = state->invalidateRegions(regionsToInvalidate,
                                        CNE, blockCount, 0,
                                        /* invalidateGlobals = */ true);
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp?rev=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp Sat Aug 27 17:51:26 2011
@@ -112,18 +112,22 @@
   QualType resultTy;
   bool isLVal = false;
 
-  if (CallE) {
-    isLVal = CallE->isLValue();
-    const Expr *Callee = CallE->getCallee();
-    if (const FunctionDecl *FD = State->getSVal(Callee).getAsFunctionDecl())
-      resultTy = FD->getResultType();
-    else
-      resultTy = CallE->getType();
-  }
-  else {
+  if (isObjCMessage()) {
     isLVal = isa<ObjCMessageExpr>(Msg.getOriginExpr()) &&
              Msg.getOriginExpr()->isLValue();
     resultTy = Msg.getResultType(ctx);
+  } else if (const CXXConstructExpr *Ctor =
+              CallE.dyn_cast<const CXXConstructExpr *>()) {
+    resultTy = Ctor->getType();
+  } else {
+    const CallExpr *FunctionCall = CallE.get<const CallExpr *>();
+
+    isLVal = FunctionCall->isLValue();
+    const Expr *Callee = FunctionCall->getCallee();
+    if (const FunctionDecl *FD = State->getSVal(Callee).getAsFunctionDecl())
+      resultTy = FD->getResultType();
+    else
+      resultTy = FunctionCall->getType();
   }
 
   if (isLVal)
@@ -132,25 +136,17 @@
   return resultTy;
 }
 
-SVal CallOrObjCMessage::getArgSValAsScalarOrLoc(unsigned i) const {
-  assert(i < getNumArgs());
-  if (CallE) return State->getSValAsScalarOrLoc(CallE->getArg(i));
-  QualType argT = Msg.getArgType(i);
-  if (Loc::isLocType(argT) || argT->isIntegerType())
-    return Msg.getArgSVal(i, State);
-  return UnknownVal();
-}
-
 SVal CallOrObjCMessage::getFunctionCallee() const {
   assert(isFunctionCall());
   assert(!isCXXCall());
-  const Expr *callee = CallE->getCallee()->IgnoreParens();
-  return State->getSVal(callee);
+  const Expr *Fun = CallE.get<const CallExpr *>()->getCallee()->IgnoreParens();
+  return State->getSVal(Fun);
 }
 
 SVal CallOrObjCMessage::getCXXCallee() const {
   assert(isCXXCall());
+  const CallExpr *ActualCall = CallE.get<const CallExpr *>();
   const Expr *callee =
-    cast<CXXMemberCallExpr>(CallE)->getImplicitObjectArgument();
+    cast<CXXMemberCallExpr>(ActualCall)->getImplicitObjectArgument();
   return State->getSVal(callee);  
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Sat Aug 27 17:51:26 2011
@@ -136,41 +136,38 @@
            new_state;
 }
 
-const ProgramState *ProgramState::invalidateRegions(const MemRegion * const *Begin,
-                                          const MemRegion * const *End,
-                                          const Expr *E, unsigned Count,
-                                          StoreManager::InvalidatedSymbols *IS,
-                                          bool invalidateGlobals) const {
+const ProgramState *
+ProgramState::invalidateRegions(ArrayRef<const MemRegion *> Regions,
+                                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(Regions, E, Count,
+                                 invalidated, invalidateGlobals);
   }
-  return invalidateRegionsImpl(Begin, End, E, Count, *IS, invalidateGlobals);
+  return invalidateRegionsImpl(Regions, E, Count, *IS, invalidateGlobals);
 }
 
 const ProgramState *
-ProgramState::invalidateRegionsImpl(const MemRegion * const *Begin,
-                               const MemRegion * const *End,
-                               const Expr *E, unsigned Count,
-                               StoreManager::InvalidatedSymbols &IS,
-                               bool invalidateGlobals) const {
+ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
+                                    const Expr *E, unsigned Count,
+                                    StoreManager::InvalidatedSymbols &IS,
+                                    bool invalidateGlobals) const {
   ProgramStateManager &Mgr = getStateManager();
   SubEngine* Eng = Mgr.getOwningEngine();
  
   if (Eng && Eng->wantsRegionChangeUpdate(this)) {
-    StoreManager::InvalidatedRegions Regions;
+    StoreManager::InvalidatedRegions Invalidated;
     const StoreRef &newStore
-      = Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS,
-                                        invalidateGlobals, &Regions);
+      = Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, IS,
+                                        invalidateGlobals, &Invalidated);
     const ProgramState *newState = makeWithStore(newStore);
-    return Eng->processRegionChanges(newState, &IS,
-                                     &Regions.front(),
-                                     &Regions.back()+1);
+    return Eng->processRegionChanges(newState, &IS, Regions, Invalidated);
   }
 
   const StoreRef &newStore =
-    Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS,
+    Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, IS,
                                     invalidateGlobals, NULL);
   return makeWithStore(newStore);
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=138716&r1=138715&r2=138716&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Sat Aug 27 17:51:26 2011
@@ -236,13 +236,11 @@
   // Binding values to regions.
   //===-------------------------------------------------------------------===//
 
-  StoreRef invalidateRegions(Store store,
-                             const MemRegion * const *Begin,
-                             const MemRegion * const *End,
+  StoreRef invalidateRegions(Store store, ArrayRef<const MemRegion *> Regions,
                              const Expr *E, unsigned Count,
                              InvalidatedSymbols &IS,
                              bool invalidateGlobals,
-                             InvalidatedRegions *Regions);
+                             InvalidatedRegions *Invalidated);
 
 public:   // Made public for helper classes.
 
@@ -721,21 +719,21 @@
 }
 
 StoreRef RegionStoreManager::invalidateRegions(Store store,
-                                               const MemRegion * const *I,
-                                               const MemRegion * const *E,
+                                            ArrayRef<const MemRegion *> Regions,
                                                const Expr *Ex, unsigned Count,
                                                InvalidatedSymbols &IS,
                                                bool invalidateGlobals,
-                                               InvalidatedRegions *Regions) {
+                                              InvalidatedRegions *Invalidated) {
   invalidateRegionsWorker W(*this, StateMgr,
                             RegionStoreManager::GetRegionBindings(store),
-                            Ex, Count, IS, Regions, invalidateGlobals);
+                            Ex, Count, IS, Invalidated, invalidateGlobals);
 
   // Scan the bindings and generate the clusters.
   W.GenerateClusters();
 
-  // Add I .. E to the worklist.
-  for ( ; I != E; ++I)
+  // Add the regions to the worklist.
+  for (ArrayRef<const MemRegion *>::iterator
+       I = Regions.begin(), E = Regions.end(); I != E; ++I)
     W.AddToWorkList(*I);
 
   W.RunWorkList();
@@ -755,8 +753,8 @@
 
     // Even if there are no bindings in the global scope, we still need to
     // record that we touched it.
-    if (Regions)
-      Regions->push_back(GS);
+    if (Invalidated)
+      Invalidated->push_back(GS);
   }
 
   return StoreRef(B.getRootWithoutRetain(), *this);





More information about the cfe-commits mailing list