diff options
-rw-r--r-- | lib/Analysis/CheckDeadStores.cpp | 3 | ||||
-rw-r--r-- | test/Analysis/dead-stores.c | 21 |
2 files changed, 23 insertions, 1 deletions
diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp index ad63eb4122..ec13328447 100644 --- a/lib/Analysis/CheckDeadStores.cpp +++ b/lib/Analysis/CheckDeadStores.cpp @@ -84,7 +84,8 @@ public: 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 ae5e3e3673..7cf8c31cd2 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -406,3 +406,24 @@ int f24_D(int y) { 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; +} + |