diff options
Diffstat (limited to 'include/clang')
4 files changed, 42 insertions, 10 deletions
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 78a4f8928b..413b3cf4ea 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -76,6 +76,7 @@ protected: protected: const void *getData1() const { return Data.first; } const void *getData2() const { return Data.second; } + void setData2(const void *d) { Data.second = d; } public: /// Create a new ProgramPoint object that is the same as the original @@ -195,7 +196,7 @@ public: class PostStmt : public StmtPoint { protected: PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L, - const ProgramPointTag *tag =0) + const ProgramPointTag *tag = 0) : StmtPoint(S, data, k, L, tag) {} public: @@ -270,15 +271,29 @@ public: } }; +/// \class Represents a program point after a store evaluation. class PostStore : public PostStmt { public: - PostStore(const Stmt *S, const LocationContext *L, + /// Construct the post store point. + /// \param Loc can be used to store the information about the location + /// used in the form it was uttered in the code. + PostStore(const Stmt *S, const LocationContext *L, const void *Loc, const ProgramPointTag *tag = 0) - : PostStmt(S, PostStoreKind, L, tag) {} + : PostStmt(S, PostStoreKind, L, tag) { + assert(getData2() == 0); + setData2(Loc); + } static bool classof(const ProgramPoint* Location) { return Location->getKind() == PostStoreKind; } + + /// \brief Returns the information about the location used in the store, + /// how it was uttered in the code. + const void *getLocationValue() const { + return getData2(); + } + }; class PostLValue : public PostStmt { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 3bed6daf7c..052916177f 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -114,6 +114,18 @@ public: return Pred->getLocationContext()->getAnalysisDeclContext(); } + /// \brief If the given node corresponds to a PostStore program point, retrieve + /// the location region as it was uttered in the code. + /// + /// This utility can be useful for generating extensive diagnostics, for + /// example, for finding variables that the given symbol was assigned to. + static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) { + ProgramPoint L = N->getLocation(); + if (const PostStore *PSL = dyn_cast<PostStore>(&L)) + return reinterpret_cast<const MemRegion*>(PSL->getLocationValue()); + return 0; + } + /// \brief Generates a new transition in the program state graph /// (ExplodedGraph). Uses the default CheckerContext predecessor node. /// diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 52c1a2a41c..e8c4688293 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -426,8 +426,7 @@ protected: /// evalBind - Handle the semantics of binding a value to a specific location. /// This method is used by evalStore, VisitDeclStmt, and others. void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, - SVal location, SVal Val, bool atDeclInit = false, - ProgramPoint::Kind PP = ProgramPoint::PostStmtKind); + SVal location, SVal Val, bool atDeclInit = false); public: // FIXME: 'tag' should be removed, and a LocationContext should be used diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 420231ad0e..87bc0df090 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -123,8 +123,6 @@ public: virtual MemRegionManager* getMemRegionManager() const = 0; - std::string getString() const; - const MemSpaceRegion *getMemorySpace() const; const MemRegion *getBaseRegion() const; @@ -142,10 +140,16 @@ public: /// Compute the offset within the top level memory object. RegionOffset getAsOffset() const; + /// \brief Get a string representation of a region for debug use. + std::string getString() const; + virtual void dumpToStream(raw_ostream &os) const; void dump() const; + /// \brief Print the region for use in diagnostics. + virtual void dumpPretty(raw_ostream &os) const; + Kind getKind() const { return kind; } template<typename RegionTy> const RegionTy* getAs() const; @@ -814,6 +818,8 @@ public: static bool classof(const MemRegion* R) { return R->getKind() == VarRegionKind; } + + void dumpPretty(raw_ostream &os) const; }; /// CXXThisRegion - Represents the region for the implicit 'this' parameter @@ -853,9 +859,6 @@ class FieldRegion : public DeclRegion { : DeclRegion(fd, sReg, FieldRegionKind) {} public: - - void dumpToStream(raw_ostream &os) const; - const FieldDecl *getDecl() const { return cast<FieldDecl>(D); } QualType getValueType() const { @@ -873,6 +876,9 @@ public: static bool classof(const MemRegion* R) { return R->getKind() == FieldRegionKind; } + + void dumpToStream(raw_ostream &os) const; + void dumpPretty(raw_ostream &os) const; }; class ObjCIvarRegion : public DeclRegion { |