]> granicus.if.org Git - clang/commitdiff
Teach GRExprEngine to handle the initialization of the condition variable of a Switch...
authorTed Kremenek <kremenek@apple.com>
Thu, 24 Dec 2009 00:40:03 +0000 (00:40 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 24 Dec 2009 00:40:03 +0000 (00:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92102 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/GRExprEngine.h
lib/Analysis/GRExprEngine.cpp
test/Analysis/misc-ps-region-store.cpp

index 6aa4be345688787baa468e017c1fe77e701bb963..3f5e16532ed486946f7e754f5a3f405294be9526 100644 (file)
@@ -293,10 +293,10 @@ protected:
   void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, ExplodedNode* Pred,
                         ExplodedNodeSet& Dst);
 
-  /// VisitIfStmtCondInit - Transfer function for handling the initialization
-  ///  of a condition variable in an IfStmt.
-  void VisitIfStmtCondInit(IfStmt *IS, ExplodedNode *Pred,
-                           ExplodedNodeSet& Dst);
+  /// VisitCondInit - Transfer function for handling the initialization
+  ///  of a condition variable in an IfStmt, SwitchStmt, etc.
+  void VisitCondInit(VarDecl *VD, Stmt *S, ExplodedNode *Pred,
+                     ExplodedNodeSet& Dst);
   
   void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
                          ExplodedNodeSet& Dst);
index ceefea81f5c10b923f509401538ce6e6c04ebaab..d7486f85134c98f1b9f5c3a7cd2d54ace6bc8516 100644 (file)
@@ -665,7 +665,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
     case Stmt::IfStmtClass:
       // This case isn't for branch processing, but for handling the
       // initialization of a condition variable.
-      VisitIfStmtCondInit(cast<IfStmt>(S), Pred, Dst);
+      VisitCondInit(cast<IfStmt>(S)->getConditionVariable(), S, Pred, Dst);
       break;
 
     case Stmt::InitListExprClass:
@@ -733,6 +733,12 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
     case Stmt::StringLiteralClass:
       VisitLValue(cast<StringLiteral>(S), Pred, Dst);
       break;
+      
+    case Stmt::SwitchStmtClass:
+      // This case isn't for branch processing, but for handling the
+      // initialization of a condition variable.
+      VisitCondInit(cast<SwitchStmt>(S)->getConditionVariable(), S, Pred, Dst);
+      break;
 
     case Stmt::UnaryOperatorClass: {
       UnaryOperator *U = cast<UnaryOperator>(S);
@@ -2230,12 +2236,10 @@ void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
   }
 }
 
-void GRExprEngine::VisitIfStmtCondInit(IfStmt *IS, ExplodedNode *Pred,
-                                       ExplodedNodeSet& Dst) {
-  
-  VarDecl* VD = IS->getConditionVariable();
-  Expr* InitEx = VD->getInit();
+void GRExprEngine::VisitCondInit(VarDecl *VD, Stmt *S,
+                                 ExplodedNode *Pred, ExplodedNodeSet& Dst) {
   
+  Expr* InitEx = VD->getInit();  
   ExplodedNodeSet Tmp;
   Visit(InitEx, Pred, Tmp);
 
@@ -2255,7 +2259,7 @@ void GRExprEngine::VisitIfStmtCondInit(IfStmt *IS, ExplodedNode *Pred,
                                             Builder->getCurrentBlockCount());
     }
       
-    EvalBind(Dst, IS, IS, N, state,
+    EvalBind(Dst, S, S, N, state,
              loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
   }
 }
index 7b911a5c82dece76877f80d0b7bd73033f1f2740..e9d6d938710fc72b65fbd84de744b8a7456003e7 100644 (file)
@@ -41,3 +41,21 @@ int test_init_in_condition() {
   }
   return 0;
 }
+
+int test_init_in_condition_switch() {
+  switch (int x = test_init_in_condition_aux()) { // no-warning
+    case 1:
+      return 0;
+    case 2:
+      if (x == 2)
+        return 0;
+      else {
+        // Unreachable.
+        int *p = 0;
+        *p = 0xDEADBEEF; // no-warning
+      }
+    default:
+      break;
+  }
+  return 0;
+}