diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | 809500fc2c13c8173a16b052304d983864e4a1e1 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h | |
parent | be7c9ec198dcdb5bf73a35bfbb00b3333cb87909 (diff) | |
download | src-809500fc2c13c8173a16b052304d983864e4a1e1.tar.gz src-809500fc2c13c8173a16b052304d983864e4a1e1.zip |
Vendor import of clang trunk r178860:vendor/clang/clang-trunk-r178860
Notes
Notes:
svn path=/vendor/clang/dist/; revision=249261
svn path=/vendor/clang/clang-trunk-r178860/; revision=249262; tag=vendor/clang/clang-trunk-r178860
Diffstat (limited to 'include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h')
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h | 143 |
1 files changed, 100 insertions, 43 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 78b254222e9e..33e4431eb4be 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -16,15 +16,15 @@ #ifndef LLVM_CLANG_GR_EXPRENGINE #define LLVM_CLANG_GR_EXPRENGINE +#include "clang/AST/Expr.h" +#include "clang/AST/Type.h" #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" -#include "clang/AST/Expr.h" -#include "clang/AST/Type.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" namespace clang { @@ -44,8 +44,19 @@ namespace ento { class AnalysisManager; class CallEvent; class SimpleCall; +class CXXConstructorCall; class ExprEngine : public SubEngine { +public: + /// The modes of inlining, which override the default analysis-wide settings. + enum InliningModes { + /// Follow the default settings for inlining callees. + Inline_Regular = 0, + /// Do minimal inlining of callees. + Inline_Minimal = 0x1 + }; + +private: AnalysisManager &AMgr; AnalysisDeclContextManager &AnalysisDeclContexts; @@ -64,15 +75,6 @@ class ExprEngine : public SubEngine { /// svalBuilder - SValBuilder object that creates SVals from expressions. SValBuilder &svalBuilder; - /// EntryNode - The immediate predecessor node. - ExplodedNode *EntryNode; - - /// CleanedState - The state for EntryNode "cleaned" of all dead - /// variables and symbols (as determined by a liveness analysis). - ProgramStateRef CleanedState; - - /// currStmt - The current block-level statement. - const Stmt *currStmt; unsigned int currStmtIdx; const NodeBuilderContext *currBldrCtx; @@ -92,10 +94,14 @@ class ExprEngine : public SubEngine { /// AnalysisConsumer. It can be null. SetOfConstDecls *VisitedCallees; + /// The flag, which specifies the mode of inlining for the engine. + InliningModes HowToInline; + public: ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfConstDecls *VisitedCalleesIn, - FunctionSummariesTy *FS); + FunctionSummariesTy *FS, + InliningModes HowToInlineIn); ~ExprEngine(); @@ -140,11 +146,12 @@ public: void enqueueEndOfPath(ExplodedNodeSet &S); void GenerateCallExitNode(ExplodedNode *N); - /// ViewGraph - Visualize the ExplodedGraph created by executing the - /// simulation. + /// Visualize the ExplodedGraph created by executing the simulation. void ViewGraph(bool trim = false); - void ViewGraph(ExplodedNode** Beg, ExplodedNode** End); + /// Visualize a trimmed ExplodedGraph that only contains paths to the given + /// nodes. + void ViewGraph(ArrayRef<const ExplodedNode*> Nodes); /// getInitialState - Return the initial state used for the root vertex /// in the ExplodedGraph. @@ -154,26 +161,33 @@ public: const ExplodedGraph& getGraph() const { return G; } /// \brief Run the analyzer's garbage collection - remove dead symbols and - /// bindings. + /// bindings from the state. /// - /// \param Node - The predecessor node, from which the processing should - /// start. - /// \param Out - The returned set of output nodes. - /// \param ReferenceStmt - Run garbage collection using the symbols, - /// which are live before the given statement. - /// \param LC - The location context of the ReferenceStmt. - /// \param DiagnosticStmt - the statement used to associate the diagnostic - /// message, if any warnings should occur while removing the dead (leaks - /// are usually reported here). - /// \param K - In some cases it is possible to use PreStmt kind. (Do - /// not use it unless you know what you are doing.) - /// If the ReferenceStmt is NULL, everything is this and parent contexts is - /// considered live. - /// If the stack frame context is NULL, everything on stack is considered - /// dead. + /// Checkers can participate in this process with two callbacks: + /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation + /// class for more information. + /// + /// \param Node The predecessor node, from which the processing should start. + /// \param Out The returned set of output nodes. + /// \param ReferenceStmt The statement which is about to be processed. + /// Everything needed for this statement should be considered live. + /// A null statement means that everything in child LocationContexts + /// is dead. + /// \param LC The location context of the \p ReferenceStmt. A null location + /// context means that we have reached the end of analysis and that + /// all statements and local variables should be considered dead. + /// \param DiagnosticStmt Used as a location for any warnings that should + /// occur while removing the dead (e.g. leaks). By default, the + /// \p ReferenceStmt is used. + /// \param K Denotes whether this is a pre- or post-statement purge. This + /// must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an + /// entire location context is being cleared, in which case the + /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise, + /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default) + /// and \p ReferenceStmt must be valid (non-null). void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, - const Stmt *ReferenceStmt, const StackFrameContext *LC, - const Stmt *DiagnosticStmt, + const Stmt *ReferenceStmt, const LocationContext *LC, + const Stmt *DiagnosticStmt = 0, ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); /// processCFGElement - Called by CoreEngine. Used to generate new successor @@ -210,6 +224,15 @@ public: const CFGBlock *DstT, const CFGBlock *DstF); + /// Called by CoreEngine. Used to processing branching behavior + /// at static initalizers. + void processStaticInitializer(const DeclStmt *DS, + NodeBuilderContext& BuilderCtx, + ExplodedNode *Pred, + ExplodedNodeSet &Dst, + const CFGBlock *DstT, + const CFGBlock *DstF); + /// processIndirectGoto - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a computed goto jump. void processIndirectGoto(IndirectGotoNodeBuilder& builder); @@ -218,8 +241,8 @@ public: /// nodes by processing the 'effects' of a switch statement. void processSwitch(SwitchNodeBuilder& builder); - /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path - /// nodes when the control reaches the end of a function. + /// Called by CoreEngine. Used to generate end-of-path + /// nodes when the control reaches the end of a function. void processEndOfFunction(NodeBuilderContext& BC, ExplodedNode *Pred); @@ -250,7 +273,7 @@ public: /// to the store. Used to update checkers that track region values. ProgramStateRef processRegionChanges(ProgramStateRef state, - const StoreManager::InvalidatedSymbols *invalidated, + const InvalidatedSymbols *invalidated, ArrayRef<const MemRegion *> ExplicitRegions, ArrayRef<const MemRegion *> Regions, const CallEvent *Call); @@ -416,11 +439,11 @@ public: geteagerlyAssumeBinOpBifurcationTags(); SVal evalMinus(SVal X) { - return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X; + return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X; } SVal evalComplement(SVal X) { - return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X; + return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X; } public: @@ -432,7 +455,8 @@ public: SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) { - return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R; + return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L, + R.castAs<NonLoc>(), T) : R; } SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, @@ -447,6 +471,20 @@ protected: SVal location, SVal Val, bool atDeclInit = false, const ProgramPoint *PP = 0); + /// Call PointerEscape callback when a value escapes as a result of bind. + ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, + SVal Loc, SVal Val); + /// Call PointerEscape callback when a value escapes as a result of + /// region invalidation. + /// \param[in] IsConst Specifies that the pointer is const. + ProgramStateRef notifyCheckersOfPointerEscape( + ProgramStateRef State, + const InvalidatedSymbols *Invalidated, + ArrayRef<const MemRegion *> ExplicitRegions, + ArrayRef<const MemRegion *> Regions, + const CallEvent *Call, + bool IsConst); + public: // FIXME: 'tag' should be removed, and a LocationContext should be used // instead. @@ -506,7 +544,10 @@ private: void examineStackFrames(const Decl *D, const LocationContext *LCtx, bool &IsRecursive, unsigned &StackDepth); - bool shouldInlineDecl(const Decl *D, ExplodedNode *Pred); + /// Checks our policies and decides weither the given call should be inlined. + bool shouldInlineCall(const CallEvent &Call, const Decl *D, + const ExplodedNode *Pred); + bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State); @@ -522,6 +563,22 @@ private: ExplodedNode *Pred); bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC); + + /// Models a trivial copy or move constructor or trivial assignment operator + /// call with a simple bind. + void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, + const CallEvent &Call); + + /// If the value of the given expression is a NonLoc, copy it into a new + /// temporary object region, and replace the value of the expression with + /// that. + /// + /// If \p ResultE is provided, the new region will be bound to this expression + /// instead of \p E. + ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State, + const LocationContext *LC, + const Expr *E, + const Expr *ResultE = 0); }; /// Traits for storing the call processing policy inside GDM. @@ -531,7 +588,7 @@ private: struct ReplayWithoutInlining{}; template <> struct ProgramStateTrait<ReplayWithoutInlining> : - public ProgramStatePartialTrait<void*> { + public ProgramStatePartialTrait<const void*> { static void *GDMIndex() { static int index = 0; return &index; } }; |