Add a heuristic to the dead stores checker to prune dead stores for variables annotated with '__block'.  This is overly conservative, but now the analyzer doesn't report dead stores for variables that can be updated by a block call.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90364 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp
index ad63eb4..ec13328 100644
--- a/lib/Analysis/CheckDeadStores.cpp
+++ b/lib/Analysis/CheckDeadStores.cpp
@@ -84,7 +84,8 @@
                     const LiveVariables::AnalysisDataTy& AD,
                     const LiveVariables::ValTy& Live) {
 
-    if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>())
+    if (VD->hasLocalStorage() && !Live(VD, AD) && 
+        !(VD->getAttr<UnusedAttr>() || VD->getAttr<BlocksAttr>()))
       Report(VD, dsk, Ex->getSourceRange().getBegin(),
              Val->getSourceRange());
   }
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index ae5e3e3..7cf8c31 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -406,3 +406,24 @@
   return x;
 }
 
+// This example shows that writing to a variable captured by a block means that it might
+// not be dead.
+int f25(int y) {
+  __block int x = (y > 2);
+  __block int z = 0;
+  void (^foo)() = ^{ z = x + y; };
+  x = 4; // no-warning
+  foo();
+  return z; 
+}
+
+// This test is mostly the same as 'f25', but shows that the heuristic of pruning out dead
+// stores for variables that are just marked '__block' is overly conservative.
+int f25_b(int y) {
+  // FIXME: we should eventually report a dead store here.
+  __block int x = (y > 2);
+  __block int z = 0;
+  x = 4; // no-warning
+  return z; 
+}
+