]> granicus.if.org Git - clang/commitdiff
Introduced the notion of a "derived symbol" using the class SymbolDerived.
authorTed Kremenek <kremenek@apple.com>
Wed, 15 Jul 2009 02:27:32 +0000 (02:27 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 15 Jul 2009 02:27:32 +0000 (02:27 +0000)
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

include/clang/Analysis/PathSensitive/SymbolManager.h
include/clang/Analysis/PathSensitive/ValueManager.h
lib/Analysis/SymbolManager.cpp
lib/Analysis/ValueManager.cpp

index 5aff90bc1bb5be872472d9072f1456952f032d9d..d2556cb75c7cbec48533d3ae5492c5e81f4dbc8e 100644 (file)
@@ -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);
index bbf77740c9bc38bf05b19db8bb69e2bb0563a137..a45a060de8ad8c524ff0729cee0bdd0fda4d46ea 100644 (file)
@@ -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) {
index e59d0bd437c97c3293e2bd7faf274b652d860567..ab1effab2c63f1cb72d54822646ba99241ce3ac1 100644 (file)
@@ -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;
index 724a2e92d7448be5c08252429aa3acd4f7d31648..c9e24223df11bb233beda4c8183303a10688811a 100644 (file)
@@ -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()));