diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-07-15 02:27:32 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-07-15 02:27:32 +0000 |
commit | fb91c70e24e20f8704edf9bc5049ffbe7e234a38 (patch) | |
tree | 4d629ffc854cd8ee0a9b9ff57e370a6dcad72c16 | |
parent | aa8bc7e977ad3c53a8472e8d215d21e1dff042de (diff) |
Introduced the notion of a "derived symbol" using the class SymbolDerived.
SymbolDerived allows us to model symbolic values that are related to other
symbols via a region hierarchy. For example, SymbolDerived can be used to model
individual values of a symbolic array.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75728 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/PathSensitive/SymbolManager.h | 40 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/ValueManager.h | 3 | ||||
-rw-r--r-- | lib/Analysis/SymbolManager.cpp | 28 | ||||
-rw-r--r-- | lib/Analysis/ValueManager.cpp | 16 |
4 files changed, 86 insertions, 1 deletions
diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index 5aff90bc1b..d2556cb75c 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -30,6 +30,7 @@ namespace llvm { namespace clang { class MemRegion; + class TypedRegion; class ASTContext; class BasicValueFactory; } @@ -38,7 +39,9 @@ namespace clang { class SymExpr : public llvm::FoldingSetNode { public: - enum Kind { BEGIN_SYMBOLS, RegionValueKind, ConjuredKind, END_SYMBOLS, + enum Kind { BEGIN_SYMBOLS, + RegionValueKind, ConjuredKind, DerivedKind, + END_SYMBOLS, SymIntKind, SymSymKind }; private: Kind K; @@ -156,6 +159,38 @@ public: return SE->getKind() == ConjuredKind; } }; + +class SymbolDerived : public SymbolData { + SymbolRef parentSymbol; + const TypedRegion *R; + +public: + SymbolDerived(SymbolID sym, SymbolRef parent, const TypedRegion *r) + : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {} + + SymbolRef getParentSymbol() const { return parentSymbol; } + const TypedRegion *getRegion() const { return R; } + + QualType getType(ASTContext&) const; + + void dumpToStream(llvm::raw_ostream &os) const; + + static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, + const TypedRegion *r) { + profile.AddInteger((unsigned) DerivedKind); + profile.AddPointer(r); + profile.AddPointer(parent); + } + + virtual void Profile(llvm::FoldingSetNodeID& profile) { + Profile(profile, parentSymbol, R); + } + + // Implement isa<T> support. + static inline bool classof(const SymExpr* SE) { + return SE->getKind() == DerivedKind; + } +}; // SymIntExpr - Represents symbolic expression like 'x' + 3. class SymIntExpr : public SymExpr { @@ -268,6 +303,9 @@ public: const void* SymbolTag = 0) { return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag); } + + const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol, + const TypedRegion *R); const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType t); diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h index bbf77740c9..a45a060de8 100644 --- a/include/clang/Analysis/PathSensitive/ValueManager.h +++ b/include/clang/Analysis/PathSensitive/ValueManager.h @@ -82,6 +82,9 @@ public: SVal getConjuredSymbolVal(const Expr *E, unsigned Count); SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count); + SVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, + const TypedRegion *R); + SVal getFunctionPointer(const FunctionDecl* FD); NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) { diff --git a/lib/Analysis/SymbolManager.cpp b/lib/Analysis/SymbolManager.cpp index e59d0bd437..ab1effab2c 100644 --- a/lib/Analysis/SymbolManager.cpp +++ b/lib/Analysis/SymbolManager.cpp @@ -68,6 +68,11 @@ void SymbolConjured::dumpToStream(llvm::raw_ostream& os) const { os << "conj_$" << getSymbolID(); } +void SymbolDerived::dumpToStream(llvm::raw_ostream& os) const { + os << "derived_$" << getSymbolID() << '{' + << getParentSymbol() << ',' << getRegion() << '}'; +} + void SymbolRegionValue::dumpToStream(llvm::raw_ostream& os) const { os << "reg_$" << getSymbolID() << "<" << R << ">"; } @@ -106,6 +111,24 @@ SymbolManager::getConjuredSymbol(const Stmt* E, QualType T, unsigned Count, return cast<SymbolConjured>(SD); } +const SymbolDerived* +SymbolManager::getDerivedSymbol(SymbolRef parentSymbol, + const TypedRegion *R) { + + llvm::FoldingSetNodeID profile; + SymbolDerived::Profile(profile, parentSymbol, R); + void* InsertPos; + SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); + if (!SD) { + SD = (SymExpr*) BPAlloc.Allocate<SymbolDerived>(); + new (SD) SymbolDerived(SymbolCounter, parentSymbol, R); + DataSet.InsertNode(SD, InsertPos); + ++SymbolCounter; + } + + return cast<SymbolDerived>(SD); +} + const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& v, @@ -146,6 +169,11 @@ QualType SymbolConjured::getType(ASTContext&) const { return T; } + +QualType SymbolDerived::getType(ASTContext& Ctx) const { + return R->getValueType(Ctx); +} + QualType SymbolRegionValue::getType(ASTContext& C) const { if (!T.isNull()) return T; diff --git a/lib/Analysis/ValueManager.cpp b/lib/Analysis/ValueManager.cpp index 724a2e92d7..c9e24223df 100644 --- a/lib/Analysis/ValueManager.cpp +++ b/lib/Analysis/ValueManager.cpp @@ -118,6 +118,22 @@ SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T, return UnknownVal(); } + +SVal ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, + const TypedRegion *R) { + SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R); + + QualType T = R->getValueType(R->getContext()); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + if (T->isIntegerType() && T->isScalarType()) + return nonloc::SymbolVal(sym); + + return UnknownVal(); +} + SVal ValueManager::getFunctionPointer(const FunctionDecl* FD) { CodeTextRegion* R = MemMgr.getCodeTextRegion(FD, Context.getPointerType(FD->getType())); |