]> granicus.if.org Git - clang/commitdiff
Enhance dataflow analyses to recognize branch statements in the CFG used as hooks...
authorTed Kremenek <kremenek@apple.com>
Thu, 24 Dec 2009 02:40:30 +0000 (02:40 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 24 Dec 2009 02:40:30 +0000 (02:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92119 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/Visitors/CFGRecStmtVisitor.h
include/clang/Analysis/Visitors/CFGStmtVisitor.h
lib/Analysis/LiveVariables.cpp

index 83700a3a346d9e420ccdb313dd34adc119db538a..75a4ac66012e7adf6d2f4b74f8a13c40860f2fc0 100644 (file)
@@ -25,6 +25,25 @@ public:
   void VisitStmt(Stmt* S) {
     static_cast< ImplClass* >(this)->VisitChildren(S);
   }
+  
+  void VisitConditionVariableInit(Stmt *S) {
+    assert(S == this->getCurrentBlkStmt());
+    VarDecl *CondVar = 0;
+    switch (S->getStmtClass()) {
+#define CONDVAR_CASE(CLASS) \
+case Stmt::CLASS ## Class:\
+CondVar = cast<CLASS>(S)->getConditionVariable();\
+break;
+        CONDVAR_CASE(IfStmt)
+        CONDVAR_CASE(ForStmt)
+        CONDVAR_CASE(SwitchStmt)
+        CONDVAR_CASE(WhileStmt)
+#undef CONDVAR_CASE
+      default:
+        assert(false && "Infeasible");
+    }    
+    static_cast<ImplClass*>(this)->Visit(CondVar->getInit());
+  }
 
   // Defining operator() allows the visitor to be used as a C++ style functor.
   void operator()(Stmt* S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);}
index 426b9ccd8a23a0db03ccd4db4e2452aafe65d34e..8a85ec15cdceaa12acf0af554f96790505abd98c 100644 (file)
@@ -54,6 +54,13 @@ public:
     else
       return RetTy();
   }
+  
+  /// VisitConditionVariableInit - Handle the initialization of condition
+  ///  variables at branches.  Valid statements include IfStmt, ForStmt,
+  ///  WhileStmt, and SwitchStmt.
+  RetTy VisitConditionVariableInit(Stmt *S) {
+    return RetTy();
+  }
 
   /// BlockVisit_XXX - Visitor methods for visiting the "root" statements in
   /// CFGBlocks.  Root statements are the statements that appear explicitly in
@@ -65,6 +72,11 @@ public:
     NullifyStmt cleanup(CurrentBlkStmt);
 
     switch (S->getStmtClass()) {
+      case Stmt::IfStmtClass:
+      case Stmt::ForStmtClass:
+      case Stmt::WhileStmtClass:
+      case Stmt::SwitchStmtClass:
+        return static_cast<ImplClass*>(this)->VisitConditionVariableInit(S);
 
       DISPATCH_CASE(StmtExpr)
       DISPATCH_CASE(ConditionalOperator)
index 84e268f3fdaa3fb7acf97e874ad25a79c4972289..e6fd1627e2d3b279cca203a2e30491117ce0826f 100644 (file)
@@ -112,6 +112,11 @@ public:
   void VisitUnaryOperator(UnaryOperator* U);
   void Visit(Stmt *S);
   void VisitTerminator(CFGBlock* B);
+  
+  /// VisitConditionVariableInit - Handle the initialization of condition
+  ///  variables at branches.  Valid statements include IfStmt, ForStmt,
+  ///  WhileStmt, and SwitchStmt.
+  void VisitConditionVariableInit(Stmt *S);
 
   void SetTopValue(LiveVariables::ValTy& V) {
     V = AD.AlwaysLive;
@@ -126,7 +131,9 @@ void TransferFuncs::Visit(Stmt *S) {
     if (AD.Observer)
       AD.Observer->ObserveStmt(S,AD,LiveState);
 
-    if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
+    if (getCFG().isBlkExpr(S))
+      LiveState(S, AD) = Dead;
+
     StmtVisitor<TransferFuncs,void>::Visit(S);
   }
   else if (!getCFG().isBlkExpr(S)) {
@@ -142,6 +149,11 @@ void TransferFuncs::Visit(Stmt *S) {
     LiveState(S,AD) = Alive;
   }
 }
+  
+void TransferFuncs::VisitConditionVariableInit(Stmt *S) {
+  assert(!getCFG().isBlkExpr(S));
+  CFGRecStmtVisitor<TransferFuncs>::VisitConditionVariableInit(S);
+}
 
 void TransferFuncs::VisitTerminator(CFGBlock* B) {