[cfe-commits] r47586 - in /cfe/trunk: Analysis/GRExprEngine.cpp Analysis/RValues.cpp Analysis/SymbolManager.cpp Analysis/ValueState.cpp include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/RValues.h include/clang/Analysis/PathSensitive/SymbolManager.h

Ted Kremenek kremenek at apple.com
Mon Feb 25 18:15:56 PST 2008


Author: kremenek
Date: Mon Feb 25 20:15:56 2008
New Revision: 47586

URL: http://llvm.org/viewvc/llvm-project?rev=47586&view=rev
Log:
Added lazy "symbolication" of parameter variables and global variables.
Added recording of divide-by-zero and divide-by-uninitialized nodes.

Modified:
    cfe/trunk/Analysis/GRExprEngine.cpp
    cfe/trunk/Analysis/RValues.cpp
    cfe/trunk/Analysis/SymbolManager.cpp
    cfe/trunk/Analysis/ValueState.cpp
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h
    cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h

Modified: cfe/trunk/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRExprEngine.cpp?rev=47586&r1=47585&r2=47586&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Mon Feb 25 20:15:56 2008
@@ -396,6 +396,22 @@
 
 void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst){
 
+  if (VarDecl* VD = dyn_cast<VarDecl>(D->getDecl()))
+    if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
+
+      StateTy StOld = Pred->getState();
+      StateTy St = Symbolicate(StOld, VD);
+
+      if (!(St == StOld)) {
+        if (D != CurrentStmt)
+          Nodify(Dst, D, Pred, St);
+        else
+          Nodify(Dst, D, Pred, SetRVal(St, D, GetRVal(St, D)));
+        
+        return;
+      }
+    }
+  
   if (D != CurrentStmt) {
     Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
     return;
@@ -796,7 +812,20 @@
   
   Ex = Ex->IgnoreParens();
   
-  if (isa<DeclRefExpr>(Ex)) {
+  if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex)) {
+    
+    if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
+      if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
+        
+        StateTy StOld = Pred->getState();
+        StateTy St = Symbolicate(StOld, VD);
+        
+        if (!(St == StOld)) {
+          Nodify(Dst, Ex, Pred, St);
+          return;
+        }
+      }
+    
     Dst.Add(Pred);
     return;
   }
@@ -857,20 +886,33 @@
       
       if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
           && RHS->getType()->isIntegerType()) {
+
+        // Check if the denominator is uninitialized.
         
-        // Check for divide/remaindner-by-zero.
-        
-        // First, "assume" that the denominator is 0.
+        if (RightV.isUninit()) {
+          NodeTy* DivUninit = Builder->generateNode(B, St, N2);
+          
+          if (DivUninit) {
+            DivUninit->markAsSink();
+            BadDivides.insert(DivUninit);
+          }
+          
+          continue;
+        }
+          
+        // Check for divide/remainder-by-zero.
+        //
+        // First, "assume" that the denominator is 0 or uninitialized.
         
         bool isFeasible = false;
-        StateTy ZeroSt = Assume(St, RightV, false, isFeasible);
+        StateTy ZeroSt =  Assume(St, RightV, false,isFeasible);
         
         if (isFeasible) {
           NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
           
           if (DivZeroNode) {
             DivZeroNode->markAsSink();
-            DivZeroes.insert(DivZeroNode);
+            BadDivides.insert(DivZeroNode);
           }
         }
         
@@ -1003,8 +1045,19 @@
           if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
               && RHS->getType()->isIntegerType()) {
             
-             // Check for divide/remainder-by-zero.
-                        
+            // Check if the denominator is uninitialized.
+                
+            if (RightV.isUninit()) {
+              NodeTy* DivUninit = Builder->generateNode(B, St, N2);
+              
+              if (DivUninit) {
+                DivUninit->markAsSink();
+                BadDivides.insert(DivUninit);
+              }
+              
+              continue;
+            }
+            
             // First, "assume" that the denominator is 0.
             
             bool isFeasible = false;
@@ -1015,7 +1068,7 @@
               
               if (DivZeroNode) {
                 DivZeroNode->markAsSink();
-                DivZeroes.insert(DivZeroNode);
+                BadDivides.insert(DivZeroNode);
               }
             }
             

Modified: cfe/trunk/Analysis/RValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/RValues.cpp?rev=47586&r1=47585&r2=47586&view=diff

==============================================================================
--- cfe/trunk/Analysis/RValues.cpp (original)
+++ cfe/trunk/Analysis/RValues.cpp Mon Feb 25 20:15:56 2008
@@ -214,7 +214,7 @@
   return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
 }
 
-RVal RVal::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
+RVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
 
   QualType T = D->getType();
   

Modified: cfe/trunk/Analysis/SymbolManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/SymbolManager.cpp?rev=47586&r1=47585&r2=47586&view=diff

==============================================================================
--- cfe/trunk/Analysis/SymbolManager.cpp (original)
+++ cfe/trunk/Analysis/SymbolManager.cpp Mon Feb 25 20:15:56 2008
@@ -16,17 +16,24 @@
 
 using namespace clang;
 
-SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
+SymbolID SymbolManager::getSymbol(VarDecl* D) {
+
+  assert (isa<ParmVarDecl>(D) || D->hasGlobalStorage());
+  
   SymbolID& X = DataToSymbol[getKey(D)];
   
   if (!X.isInitialized()) {
     X = SymbolToData.size();
-    SymbolToData.push_back(SymbolDataParmVar(D));
+    
+    if (ParmVarDecl* VD = dyn_cast<ParmVarDecl>(D))
+      SymbolToData.push_back(SymbolDataParmVar(VD));
+    else
+      SymbolToData.push_back(SymbolDataGlobalVar(D));
   }
   
   return X;
-}
-
+}  
+ 
 SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
   SymbolID& X = DataToSymbol[getKey(sym)];
   
@@ -45,6 +52,9 @@
       
     case ParmKind:
       return cast<SymbolDataParmVar>(this)->getDecl()->getType();
+
+    case GlobalKind:
+      return cast<SymbolDataGlobalVar>(this)->getDecl()->getType();
       
     case ContentsOfKind: {
       SymbolID x = cast<SymbolDataContentsOf>(this)->getSymbol();

Modified: cfe/trunk/Analysis/ValueState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ValueState.cpp?rev=47586&r1=47585&r2=47586&view=diff

==============================================================================
--- cfe/trunk/Analysis/ValueState.cpp (original)
+++ cfe/trunk/Analysis/ValueState.cpp Mon Feb 25 20:15:56 2008
@@ -78,8 +78,16 @@
   // Iterate over the variable bindings.
 
   for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
-    if (Liveness.isLive(Loc, I.getKey()))
+    if (Liveness.isLive(Loc, I.getKey())) {
       WList.push_back(I.getKey());
+      
+      RVal X = I.getData();
+      
+      for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end(); 
+           SI != SE; ++SI) {        
+        MarkedSymbols.insert(*SI);
+      }
+    }
 
   // Perform the mark-and-sweep.
 

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=47586&r1=47585&r2=47586&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Mon Feb 25 20:15:56 2008
@@ -135,9 +135,9 @@
   ///  taking a dereference on an uninitialized value.
   BadDerefTy UninitDeref;
 
-  /// DivZeroes - Nodes in the ExplodedGraph that result from evaluating
-  ///  a divide-by-zero.
-  DivZerosTy DivZeroes;
+  /// BadDivides - Nodes in the ExplodedGraph that result from evaluating
+  ///  a divide-by-zero or divide-by-uninitialized.
+  DivZerosTy BadDivides;
   
   bool StateCleaned;
   
@@ -172,20 +172,7 @@
   
   /// getInitialState - Return the initial state used for the root vertex
   ///  in the ExplodedGraph.
-  StateTy getInitialState() {
-    StateTy St = StateMgr.getInitialState();
-    
-    // Iterate the parameters.
-    FunctionDecl& F = G.getFunctionDecl();
-    
-    for (FunctionDecl::param_iterator I = F.param_begin(), E = F.param_end(); 
-                                                           I != E; ++I) {      
-      St = SetRVal(St, lval::DeclVal(*I),
-                   RVal::GetSymbolValue(SymMgr, *I));
-    }
-    
-    return St;
-  }
+  StateTy getInitialState() { return StateMgr.getInitialState(); }
   
   bool isUninitControlFlow(const NodeTy* N) const {
     return N->isSink() && UninitBranches.count(const_cast<NodeTy*>(N)) != 0;
@@ -207,6 +194,10 @@
     return N->isSink() && UninitDeref.count(const_cast<NodeTy*>(N)) != 0;
   }
   
+  bool isBadDivide(const NodeTy* N) const {
+    return N->isSink() && BadDivides.count(const_cast<NodeTy*>(N)) != 0; 
+  }
+  
   typedef BadDerefTy::iterator null_iterator;
   null_iterator null_begin() { return ExplicitNullDeref.begin(); }
   null_iterator null_end() { return ExplicitNullDeref.end(); }
@@ -271,6 +262,15 @@
     return StateMgr.GetLVal(St, Ex);
   }
   
+  StateTy Symbolicate(StateTy St, VarDecl* VD) {
+    lval::DeclVal X(VD);
+    
+    if (GetRVal(St, X).isUnknown()) {
+      return SetRVal(St, lval::DeclVal(VD), RVal::GetSymbolValue(SymMgr, VD));
+    }
+    else return St;
+  }
+  
   inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) {
     return NonLVal::MakeVal(ValMgr, X, Ex->getType(), Ex->getLocStart());
   }

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h?rev=47586&r1=47585&r2=47586&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/RValues.h Mon Feb 25 20:15:56 2008
@@ -65,7 +65,7 @@
     return !(*this == R);
   }
   
-  static RVal GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
+  static RVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
   
   inline bool isUnknown() const {
     return getRawKind() == UnknownKind;

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h?rev=47586&r1=47585&r2=47586&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h Mon Feb 25 20:15:56 2008
@@ -49,7 +49,7 @@
 
 class SymbolData {
 public:
-  enum Kind { UninitKind, ParmKind, ContentsOfKind };
+  enum Kind { UninitKind, ParmKind, GlobalKind, ContentsOfKind };
   
 private:
   uintptr_t Data;
@@ -95,6 +95,18 @@
     return D->getKind() == ParmKind;
   }
 };
+  
+class SymbolDataGlobalVar : public SymbolData {
+public:
+  SymbolDataGlobalVar(VarDecl* VD) : SymbolData(VD, GlobalKind) {}
+  
+  VarDecl* getDecl() const { return (VarDecl*) getPtr(); }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const SymbolData* D) {
+    return D->getKind() == GlobalKind;
+  }
+};
 
 class SymbolDataContentsOf : public SymbolData {
 public:
@@ -157,7 +169,7 @@
   SymbolManager();
   ~SymbolManager();
   
-  SymbolID getSymbol(ParmVarDecl* D);
+  SymbolID getSymbol(VarDecl* D);
   SymbolID getContentsOfSymbol(SymbolID sym);
   
   inline const SymbolData& getSymbolData(SymbolID ID) const {





More information about the cfe-commits mailing list