[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