Fixed LiveVariables bug where we didn't consider block-level expressions that functioned as the size of a VLA to be live.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60730 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 451e202..b41cd68 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -66,7 +66,7 @@
 public:
   typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
     
-  LiveVariables(CFG& cfg);
+  LiveVariables(ASTContext& Ctx, CFG& cfg);
   
   /// IsLive - Return true if a variable is live at beginning of a
   /// specified block.
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
index 33205d0..7a9da03 100644
--- a/include/clang/Analysis/Analyses/UninitializedValues.h
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -63,7 +63,7 @@
 public:
   typedef UninitializedValues_ValueTypes::ObserverTy ObserverTy;
 
-  UninitializedValues(CFG &cfg) { getAnalysisData().setCFG(&cfg); }
+  UninitializedValues(CFG &cfg) { getAnalysisData().setCFG(cfg); }
   
   /// IntializeValues - Create initial dataflow values and meta data for
   ///  a given CFG.  This is intended to be called by the dataflow solver.
diff --git a/include/clang/Analysis/Support/BlkExprDeclBitVector.h b/include/clang/Analysis/Support/BlkExprDeclBitVector.h
index 00513a5..675e354 100644
--- a/include/clang/Analysis/Support/BlkExprDeclBitVector.h
+++ b/include/clang/Analysis/Support/BlkExprDeclBitVector.h
@@ -25,6 +25,7 @@
 namespace clang {
   
   class Stmt;
+  class ASTContext;
 
 struct DeclBitVector_Types {
   
@@ -170,12 +171,19 @@
   //===--------------------------------------------------------------------===//
 
   class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy {
+    ASTContext* ctx;
     CFG* cfg;
   public:
-    AnalysisDataTy() {}
+    AnalysisDataTy() : ctx(0), cfg(0) {}
     virtual ~AnalysisDataTy() {}
 
-    void setCFG(CFG* c) { cfg = c; }
+    void setContext(ASTContext& c) { ctx = &c; }
+    ASTContext& getContext() {
+      assert(ctx && "ASTContext should not be NULL."); 
+      return *ctx;
+    }
+
+    void setCFG(CFG& c) { cfg = &c; }
     CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; }
     
     bool isTracked(const Stmt* S) { return cfg->isBlkExpr(S); }
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index 4b181a9..8105e38 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -13,6 +13,7 @@
 
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/CFG.h"
 #include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
@@ -95,9 +96,11 @@
 } // end anonymous namespace
 
 
-LiveVariables::LiveVariables(CFG& cfg) {
+LiveVariables::LiveVariables(ASTContext& Ctx, CFG& cfg) {
   // Register all referenced VarDecls.
-  getAnalysisData().setCFG(&cfg);
+  getAnalysisData().setCFG(cfg);
+  getAnalysisData().setContext(Ctx);
+  
   RegisterDecls R(getAnalysisData());
   cfg.VisitBlockStmts(R);
 }
@@ -270,6 +273,13 @@
       if (Expr* Init = VD->getInit())
         Visit(Init);
       
+      if (const VariableArrayType* VT =
+            AD.getContext().getAsVariableArrayType(VD->getType())) {
+        StmtIterator I(const_cast<VariableArrayType*>(VT));
+        StmtIterator E;        
+        for (; I != E; ++I) Visit(*I);
+      }
+      
       // Update liveness information by killing the VarDecl.
       unsigned bit = AD.getIdx(VD);
       LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);