diff options
Diffstat (limited to 'include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h')
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h | 173 |
1 files changed, 148 insertions, 25 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index 0d6e18e..c7de7ef 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -40,13 +40,16 @@ namespace ento { class TypedValueRegion; class VarRegion; +/// \brief Symbolic value. These values used to capture symbolic execution of +/// the program. class SymExpr : public llvm::FoldingSetNode { + virtual void anchor(); public: enum Kind { RegionValueKind, ConjuredKind, DerivedKind, ExtentKind, MetadataKind, BEGIN_SYMBOLS = RegionValueKind, END_SYMBOLS = MetadataKind, - SymIntKind, SymSymKind }; + SymIntKind, IntSymKind, SymSymKind, CastSymbolKind }; private: Kind K; @@ -58,21 +61,49 @@ public: Kind getKind() const { return K; } - void dump() const; + virtual void dump() const; - virtual void dumpToStream(raw_ostream &os) const = 0; + virtual void dumpToStream(raw_ostream &os) const {} virtual QualType getType(ASTContext&) const = 0; virtual void Profile(llvm::FoldingSetNodeID& profile) = 0; // Implement isa<T> support. static inline bool classof(const SymExpr*) { return true; } + + /// \brief Iterator over symbols that the current symbol depends on. + /// + /// For SymbolData, it's the symbol itself; for expressions, it's the + /// expression symbol and all the operands in it. Note, SymbolDerived is + /// treated as SymbolData - the iterator will NOT visit the parent region. + class symbol_iterator { + SmallVector<const SymExpr*, 5> itr; + void expand(); + public: + symbol_iterator() {} + symbol_iterator(const SymExpr *SE); + + symbol_iterator &operator++(); + const SymExpr* operator*(); + + bool operator==(const symbol_iterator &X) const; + bool operator!=(const symbol_iterator &X) const; + }; + + symbol_iterator symbol_begin() const { + return symbol_iterator(this); + } + static symbol_iterator symbol_end() { return symbol_iterator(); } }; -typedef unsigned SymbolID; +typedef const SymExpr* SymbolRef; +typedef llvm::SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy; +typedef unsigned SymbolID; +/// \brief A symbol representing data which can be stored in a memory location +/// (region). class SymbolData : public SymExpr { -private: + virtual void anchor(); const SymbolID Sym; protected: @@ -90,10 +121,7 @@ public: } }; -typedef const SymbolData* SymbolRef; -typedef llvm::SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy; - -/// A symbol representing the value of a MemRegion. +///\brief A symbol representing the value stored at a MemRegion. class SymbolRegionValue : public SymbolData { const TypedValueRegion *R; @@ -112,7 +140,7 @@ public: Profile(profile, R); } - void dumpToStream(raw_ostream &os) const; + virtual void dumpToStream(raw_ostream &os) const; QualType getType(ASTContext&) const; @@ -122,17 +150,21 @@ public: } }; -/// A symbol representing the result of an expression. +/// A symbol representing the result of an expression in the case when we do +/// not know anything about what the expression is. class SymbolConjured : public SymbolData { const Stmt *S; QualType T; unsigned Count; + const LocationContext *LCtx; const void *SymbolTag; public: - SymbolConjured(SymbolID sym, const Stmt *s, QualType t, unsigned count, + SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx, + QualType t, unsigned count, const void *symbolTag) : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count), + LCtx(lctx), SymbolTag(symbolTag) {} const Stmt *getStmt() const { return S; } @@ -141,19 +173,21 @@ public: QualType getType(ASTContext&) const; - void dumpToStream(raw_ostream &os) const; + virtual void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S, - QualType T, unsigned Count, const void *SymbolTag) { + QualType T, unsigned Count, const LocationContext *LCtx, + const void *SymbolTag) { profile.AddInteger((unsigned) ConjuredKind); profile.AddPointer(S); + profile.AddPointer(LCtx); profile.Add(T); profile.AddInteger(Count); profile.AddPointer(SymbolTag); } virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, S, T, Count, SymbolTag); + Profile(profile, S, T, Count, LCtx, SymbolTag); } // Implement isa<T> support. @@ -177,7 +211,7 @@ public: QualType getType(ASTContext&) const; - void dumpToStream(raw_ostream &os) const; + virtual void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, const TypedValueRegion *r) { @@ -210,7 +244,7 @@ public: QualType getType(ASTContext&) const; - void dumpToStream(raw_ostream &os) const; + virtual void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) { profile.AddInteger((unsigned) ExtentKind); @@ -249,7 +283,7 @@ public: QualType getType(ASTContext&) const; - void dumpToStream(raw_ostream &os) const; + virtual void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R, const Stmt *S, QualType T, unsigned Count, @@ -272,6 +306,42 @@ public: } }; +/// \brief Represents a cast expression. +class SymbolCast : public SymExpr { + const SymExpr *Operand; + /// Type of the operand. + QualType FromTy; + /// The type of the result. + QualType ToTy; + +public: + SymbolCast(const SymExpr *In, QualType From, QualType To) : + SymExpr(CastSymbolKind), Operand(In), FromTy(From), ToTy(To) { } + + QualType getType(ASTContext &C) const { return ToTy; } + + const SymExpr *getOperand() const { return Operand; } + + virtual void dumpToStream(raw_ostream &os) const; + + static void Profile(llvm::FoldingSetNodeID& ID, + const SymExpr *In, QualType From, QualType To) { + ID.AddInteger((unsigned) CastSymbolKind); + ID.AddPointer(In); + ID.Add(From); + ID.Add(To); + } + + void Profile(llvm::FoldingSetNodeID& ID) { + Profile(ID, Operand, FromTy, ToTy); + } + + // Implement isa<T> support. + static inline bool classof(const SymExpr *SE) { + return SE->getKind() == CastSymbolKind; + } +}; + /// SymIntExpr - Represents symbolic expression like 'x' + 3. class SymIntExpr : public SymExpr { const SymExpr *LHS; @@ -290,7 +360,7 @@ public: BinaryOperator::Opcode getOpcode() const { return Op; } - void dumpToStream(raw_ostream &os) const; + virtual void dumpToStream(raw_ostream &os) const; const SymExpr *getLHS() const { return LHS; } const llvm::APSInt &getRHS() const { return RHS; } @@ -315,6 +385,47 @@ public: } }; +/// IntSymExpr - Represents symbolic expression like 3 - 'x'. +class IntSymExpr : public SymExpr { + const llvm::APSInt& LHS; + BinaryOperator::Opcode Op; + const SymExpr *RHS; + QualType T; + +public: + IntSymExpr(const llvm::APSInt& lhs, BinaryOperator::Opcode op, + const SymExpr *rhs, QualType t) + : SymExpr(IntSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {} + + QualType getType(ASTContext &C) const { return T; } + + BinaryOperator::Opcode getOpcode() const { return Op; } + + virtual void dumpToStream(raw_ostream &os) const; + + const SymExpr *getRHS() const { return RHS; } + const llvm::APSInt &getLHS() const { return LHS; } + + static void Profile(llvm::FoldingSetNodeID& ID, const llvm::APSInt& lhs, + BinaryOperator::Opcode op, const SymExpr *rhs, + QualType t) { + ID.AddInteger((unsigned) IntSymKind); + ID.AddPointer(&lhs); + ID.AddInteger(op); + ID.AddPointer(rhs); + ID.Add(t); + } + + void Profile(llvm::FoldingSetNodeID& ID) { + Profile(ID, LHS, Op, RHS, T); + } + + // Implement isa<T> support. + static inline bool classof(const SymExpr *SE) { + return SE->getKind() == IntSymKind; + } +}; + /// SymSymExpr - Represents symbolic expression like 'x' + 'y'. class SymSymExpr : public SymExpr { const SymExpr *LHS; @@ -335,7 +446,7 @@ public: // generation of virtual functions. QualType getType(ASTContext &C) const { return T; } - void dumpToStream(raw_ostream &os) const; + virtual void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) { @@ -382,13 +493,18 @@ public: /// \brief Make a unique symbol for MemRegion R according to its kind. const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R); - const SymbolConjured* getConjuredSymbol(const Stmt *E, QualType T, + const SymbolConjured* getConjuredSymbol(const Stmt *E, + const LocationContext *LCtx, + QualType T, unsigned VisitCount, const void *SymbolTag = 0); - const SymbolConjured* getConjuredSymbol(const Expr *E, unsigned VisitCount, + const SymbolConjured* getConjuredSymbol(const Expr *E, + const LocationContext *LCtx, + unsigned VisitCount, const void *SymbolTag = 0) { - return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag); + return getConjuredSymbol(E, LCtx, E->getType(), + VisitCount, SymbolTag); } const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol, @@ -404,6 +520,9 @@ public: QualType T, unsigned VisitCount, const void *SymbolTag = 0); + const SymbolCast* getCastSymbol(const SymExpr *Operand, + QualType From, QualType To); + const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType t); @@ -412,6 +531,10 @@ public: return getSymIntExpr(&lhs, op, rhs, t); } + const IntSymExpr *getIntSymExpr(const llvm::APSInt& lhs, + BinaryOperator::Opcode op, + const SymExpr *rhs, QualType t); + const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t); @@ -464,7 +587,7 @@ public: bool isLive(SymbolRef sym); bool isLiveRegion(const MemRegion *region); - bool isLive(const Stmt *ExprVal) const; + bool isLive(const Stmt *ExprVal, const LocationContext *LCtx) const; bool isLive(const VarRegion *VR, bool includeStoreBindings = false) const; /// \brief Unconditionally marks a symbol as live. @@ -537,7 +660,7 @@ public: namespace llvm { static inline raw_ostream &operator<<(raw_ostream &os, - const clang::ento::SymExpr *SE) { + const clang::ento::SymExpr *SE) { SE->dumpToStream(os); return os; } |