diff options
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/CFG.h | 25 | ||||
-rw-r--r-- | include/clang/Analysis/FlowSensitive/DataflowSolver.h | 20 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/BugReporter.h | 2 | ||||
-rw-r--r-- | include/clang/Analysis/ProgramPoint.h | 153 |
4 files changed, 103 insertions, 97 deletions
diff --git a/include/clang/AST/CFG.h b/include/clang/AST/CFG.h index 1d82ee2da5..2f3183c533 100644 --- a/include/clang/AST/CFG.h +++ b/include/clang/AST/CFG.h @@ -284,7 +284,7 @@ public: //===--------------------------------------------------------------------===// CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0), - BlkExprMap(NULL), BlkEdgeSet(NULL) {}; + BlkExprMap(NULL) {}; ~CFG(); @@ -304,26 +304,9 @@ private: // It represents a map from Expr* to integers to record the set of // block-level expressions and their "statement number" in the CFG. void* BlkExprMap; - - /// BlkEdgeSet - An opaque pointer to prevent inclusion of FoldingSet.h. - /// The set contains std::pair<CFGBlock*,CFGBlock*> objects that have - /// stable references for use by the 'BlockEdge' class. This set is intended - /// to be sparse, as it only contains edges whether both the source - /// and destination block have multiple successors/predecessors. - void* BlkEdgeSet; - - /// Alloc - An internal allocator used for BlkEdgeSet. - llvm::BumpPtrAllocator Alloc; - - friend class BlockEdge; - - /// getBlockEdgeImpl - Utility method used by the class BlockEdge. The CFG - /// stores a set of interned std::pair<CFGBlock*,CFGBlock*> that can - /// be used by BlockEdge to refer to edges that cannot be represented - /// by a single pointer. - const std::pair<CFGBlock*,CFGBlock*>* getBlockEdgeImpl(const CFGBlock* B1, - const CFGBlock* B2); - + + /// Alloc - An internal allocator. + llvm::BumpPtrAllocator Alloc; }; } // end namespace clang diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h index b7cb1f8a06..169417c3d2 100644 --- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h +++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h @@ -69,12 +69,12 @@ template <> struct ItrTraits<forward_analysis_tag> { static StmtItr StmtBegin(const CFGBlock* B) { return B->begin(); } static StmtItr StmtEnd(const CFGBlock* B) { return B->end(); } - static BlockEdge PrevEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Prev) { - return BlockEdge(cfg,Prev,B); + static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) { + return BlockEdge(Prev, B); } - static BlockEdge NextEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Next) { - return BlockEdge(cfg,B,Next); + static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) { + return BlockEdge(B, Next); } }; @@ -92,12 +92,12 @@ template <> struct ItrTraits<backward_analysis_tag> { static StmtItr StmtBegin(const CFGBlock* B) { return B->rbegin(); } static StmtItr StmtEnd(const CFGBlock* B) { return B->rend(); } - static BlockEdge PrevEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Prev) { - return BlockEdge(cfg,B,Prev); + static BlockEdge PrevEdge(const CFGBlock* B, const CFGBlock* Prev) { + return BlockEdge(B, Prev); } - static BlockEdge NextEdge(CFG& cfg, const CFGBlock* B, const CFGBlock* Next) { - return BlockEdge(cfg,Next,B); + static BlockEdge NextEdge(const CFGBlock* B, const CFGBlock* Next) { + return BlockEdge(Next, B); } }; } // end namespace dataflow @@ -237,7 +237,7 @@ private: for (PrevBItr I=ItrTraits::PrevBegin(B),E=ItrTraits::PrevEnd(B); I!=E; ++I){ typename EdgeDataMapTy::iterator EI = - M.find(ItrTraits::PrevEdge(cfg,B,*I)); + M.find(ItrTraits::PrevEdge(B, *I)); if (EI != M.end()) { if (firstMerge) { @@ -287,7 +287,7 @@ private: // forward/backward analysis respectively) void UpdateEdges(CFG& cfg, const CFGBlock* B, ValTy& V) { for (NextBItr I=ItrTraits::NextBegin(B), E=ItrTraits::NextEnd(B); I!=E; ++I) - UpdateEdgeValue(ItrTraits::NextEdge(cfg,B,*I),V,*I); + UpdateEdgeValue(ItrTraits::NextEdge(B, *I),V,*I); } /// UpdateEdgeValue - Update the value associated with a given edge. diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index dddc81cc40..0cf6567652 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -57,7 +57,7 @@ public: }; class BugTypeCacheLocation : public BugType { - llvm::SmallPtrSet<void*,10> CachedErrors; + llvm::SmallSet<ProgramPoint,10> CachedErrors; public: BugTypeCacheLocation() {} virtual ~BugTypeCacheLocation() {} diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index ecb4f742c7..0ea5365692 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -25,38 +25,67 @@ namespace clang { class ProgramPoint { public: - enum Kind { BlockEntranceKind=0, - PostStmtKind=1, PostLoadKind=2, PostPurgeDeadSymbolsKind=3, - BlockExitKind=4, BlockEdgeSrcKind=5, BlockEdgeDstKind=6, - BlockEdgeAuxKind=7 }; -protected: - uintptr_t Data; + enum Kind { BlockEdgeKind=0, BlockEntranceKind, BlockExitKind, + // Keep the following three together and in this order. + PostStmtKind, PostLoadKind, PostPurgeDeadSymbolsKind }; - ProgramPoint(const void* Ptr, Kind k) { - setRawData(Ptr, k); +private: + std::pair<uintptr_t,uintptr_t> Data; + +protected: + ProgramPoint(const void* P, Kind k) + : Data(reinterpret_cast<uintptr_t>(P), (uintptr_t) k) {} + + ProgramPoint(const void* P1, const void* P2) + : Data(reinterpret_cast<uintptr_t>(P1) | 0x1, + reinterpret_cast<uintptr_t>(P2)) {} + +protected: + void* getData1NoMask() const { + assert (getKind() != BlockEdgeKind); + return reinterpret_cast<void*>(Data.first); } - ProgramPoint() : Data(0) {} + void* getData1() const { + assert (getKind() == BlockEdgeKind); + return reinterpret_cast<void*>(Data.first & ~0x1); + } - void setRawData(const void* Ptr, Kind k) { - assert ((reinterpret_cast<uintptr_t>(const_cast<void*>(Ptr)) & 0x7) == 0 - && "Address must have at least an 8-byte alignment."); - - Data = reinterpret_cast<uintptr_t>(const_cast<void*>(Ptr)) | k; + void* getData2() const { + assert (getKind() == BlockEdgeKind); + return reinterpret_cast<void*>(Data.second); } public: - unsigned getKind() const { return Data & 0x7; } - void* getRawPtr() const { return reinterpret_cast<void*>(Data & ~0x7); } - void* getRawData() const { return reinterpret_cast<void*>(Data); } + + uintptr_t getKind() const { + return Data.first & 0x1 ? (uintptr_t) BlockEdgeKind : Data.second; + } + + // For use with DenseMap. + unsigned getHashValue() const { + std::pair<void*,void*> P(reinterpret_cast<void*>(Data.first), + reinterpret_cast<void*>(Data.second)); + return llvm::DenseMapInfo<std::pair<void*,void*> >::getHashValue(P); + } static bool classof(const ProgramPoint*) { return true; } - bool operator==(const ProgramPoint & RHS) const { return Data == RHS.Data; } - bool operator!=(const ProgramPoint& RHS) const { return Data != RHS.Data; } + + bool operator==(const ProgramPoint & RHS) const { + return Data == RHS.Data; + } + + bool operator!=(const ProgramPoint& RHS) const { + return Data != RHS.Data; + } + + bool operator<(const ProgramPoint& RHS) const { + return Data < RHS.Data; + } void Profile(llvm::FoldingSetNodeID& ID) const { - ID.AddInteger(getKind()); - ID.AddPointer(getRawPtr()); + ID.AddPointer(reinterpret_cast<void*>(Data.first)); + ID.AddPointer(reinterpret_cast<void*>(Data.second)); } }; @@ -65,7 +94,7 @@ public: BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {} CFGBlock* getBlock() const { - return reinterpret_cast<CFGBlock*>(getRawPtr()); + return reinterpret_cast<CFGBlock*>(getData1NoMask()); } Stmt* getFirstStmt() const { @@ -83,7 +112,7 @@ public: BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} CFGBlock* getBlock() const { - return reinterpret_cast<CFGBlock*>(getRawPtr()); + return reinterpret_cast<CFGBlock*>(getData1NoMask()); } Stmt* getLastStmt() const { @@ -107,7 +136,7 @@ protected: public: PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {} - Stmt* getStmt() const { return (Stmt*) getRawPtr(); } + Stmt* getStmt() const { return (Stmt*) getData1NoMask(); } static bool classof(const ProgramPoint* Location) { unsigned k = Location->getKind(); @@ -134,26 +163,22 @@ public: }; class BlockEdge : public ProgramPoint { - typedef std::pair<CFGBlock*,CFGBlock*> BPair; public: - BlockEdge(CFG& cfg, const CFGBlock* B1, const CFGBlock* B2); - - /// This ctor forces the BlockEdge to be constructed using an explicitly - /// allocated pair object that is stored in the CFG. This is usually - /// used to construct edges representing jumps using computed gotos. - BlockEdge(CFG& cfg, const CFGBlock* B1, const CFGBlock* B2, bool) - : ProgramPoint(cfg.getBlockEdgeImpl(B1, B2), BlockEdgeAuxKind) {} - - - CFGBlock* getSrc() const; - CFGBlock* getDst() const; + BlockEdge(const CFGBlock* B1, const CFGBlock* B2) + : ProgramPoint(B1, B2) {} + + CFGBlock* getSrc() const { + return static_cast<CFGBlock*>(getData1()); + } + + CFGBlock* getDst() const { + return static_cast<CFGBlock*>(getData2()); + } static bool classof(const ProgramPoint* Location) { - unsigned k = Location->getKind(); - return k >= BlockEdgeSrcKind && k <= BlockEdgeAuxKind; + return Location->getKind() == BlockEdgeKind; } }; - } // end namespace clang @@ -163,32 +188,30 @@ namespace llvm { // Traits specialization for DenseMap template <> struct DenseMapInfo<clang::ProgramPoint> { - static inline clang::ProgramPoint getEmptyKey() { - uintptr_t x = - reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; - - return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); - } - - static inline clang::ProgramPoint getTombstoneKey() { - uintptr_t x = - reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; - - return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); - } - - static unsigned getHashValue(const clang::ProgramPoint& Loc) { - return DenseMapInfo<void*>::getHashValue(Loc.getRawData()); - } - - static bool isEqual(const clang::ProgramPoint& L, - const clang::ProgramPoint& R) { - return L == R; - } - - static bool isPod() { - return true; - } +static inline clang::ProgramPoint getEmptyKey() { + uintptr_t x = + reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; + return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); +} + +static inline clang::ProgramPoint getTombstoneKey() { + uintptr_t x = + reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; + return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); +} + +static unsigned getHashValue(const clang::ProgramPoint& Loc) { + return Loc.getHashValue(); +} + +static bool isEqual(const clang::ProgramPoint& L, + const clang::ProgramPoint& R) { + return L == R; +} + +static bool isPod() { + return true; +} }; } // end namespace llvm |