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

Ted Kremenek kremenek at apple.com
Sat Aug 27 20:38:37 PDT 2011


Awesome!

On Aug 27, 2011, at 3:51 PM, Jordy Rose wrote:

> 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);
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list