[CFG]

After discussion with Zhongxing, don't force the initializer of DeclStmts to be
block-level expressions.

This led to some interesting fallout:

[UninitializedValues]

Always visit the initializer of DeclStmts (do not assume they are block-level expressions).

[BasicStore]

With initializers of DeclStmts no longer block-level expressions, this causes self-referencing initializers (e.g. 'int x = x') to no longer cause the initialized variable to be live before the DeclStmt.  While this is correct, it caused BasicStore::RemoveDeadBindings() to prune off the values of these variables from the initial store (where they are set to uninitialized).  The fix is to back-port some (and only some) of the lazy-binding logic from RegionStore to
BasicStore.  Now the default values of local variables are determined lazily as opposed
to explicitly initialized.

llvm-svn: 97591
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index d4f64bc..d7072f0 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -38,13 +38,21 @@
   
 class AddStmtChoice {
 public:
-  enum Kind { NotAlwaysAdd = 0, AlwaysAdd, AlwaysAddAsLValue };
+  enum Kind { NotAlwaysAdd = 0,
+              AlwaysAdd = 1,
+              AsLValueNotAlwaysAdd = 2,
+              AlwaysAddAsLValue = 3 };
+
 public:
-  AddStmtChoice(Kind kind) : k(kind) {}  
-  bool alwaysAdd() const { return k != NotAlwaysAdd; }
-  bool asLValue() const { return k == AlwaysAddAsLValue; }
+  AddStmtChoice(Kind k)
+    : AsLValue(k >= AlwaysAddAsLValue), AlwaysAddStmt((unsigned)k & 0x1) {}
+
+  bool alwaysAdd() const { return (bool) AlwaysAddStmt; };
+  bool asLValue() const { return (bool) AsLValue; };
+
 private:
-  Kind k;
+  unsigned AsLValue : 1;
+  unsigned AlwaysAddStmt : 1;
 };
 
 /// CFGBuilder - This class implements CFG construction from an AST.
@@ -771,18 +779,10 @@
   Expr *Init = VD->getInit();
 
   if (Init) {
-    // Optimization: Don't create separate block-level statements for literals.
-    switch (Init->getStmtClass()) {
-      case Stmt::IntegerLiteralClass:
-      case Stmt::CharacterLiteralClass:
-      case Stmt::StringLiteralClass:
-        break;
-      default:
-        Block = addStmt(Init,
-                        VD->getType()->isReferenceType()
-                        ? AddStmtChoice::AlwaysAddAsLValue
-                        : AddStmtChoice::AlwaysAdd);
-    }
+    AddStmtChoice::Kind k =
+      VD->getType()->isReferenceType() ? AddStmtChoice::AsLValueNotAlwaysAdd
+                                       : AddStmtChoice::NotAlwaysAdd;
+    Visit(Init, AddStmtChoice(k));
   }
 
   // If the type of VD is a VLA, then we must process its size expressions.
diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp
index bdc0e7c..7a62864 100644
--- a/clang/lib/Analysis/UninitializedValues.cpp
+++ b/clang/lib/Analysis/UninitializedValues.cpp
@@ -134,8 +134,12 @@
   for (DeclStmt::decl_iterator I=S->decl_begin(), E=S->decl_end(); I!=E; ++I) {
     VarDecl *VD = dyn_cast<VarDecl>(*I);
     if (VD && VD->isBlockVarDecl()) {
-      if (Stmt* I = VD->getInit())
-        V(VD,AD) = AD.FullUninitTaint ? V(cast<Expr>(I),AD) : Initialized;
+      if (Stmt* I = VD->getInit()) {
+        // Visit the subexpression to check for uses of uninitialized values,
+        // even if we don't propagate that value.
+        bool isSubExprUninit = Visit(I);
+        V(VD,AD) = AD.FullUninitTaint ? isSubExprUninit : Initialized;
+      }
       else {
         // Special case for declarations of array types.  For things like:
         //