mirror of
https://github.com/intel/llvm.git
synced 2026-02-08 08:57:43 +08:00
When computing in AnalysisContext the variables referenced
by a block, also look at the contained blocks. llvm-svn: 98111
This commit is contained in:
@@ -12,15 +12,16 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/Analyses/LiveVariables.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/ParentMap.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "clang/Analysis/Analyses/LiveVariables.h"
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "clang/Analysis/Support/BumpVector.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
using namespace clang;
|
||||
@@ -207,11 +208,17 @@ class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
|
||||
BumpVector<const VarDecl*> &BEVals;
|
||||
BumpVectorContext &BC;
|
||||
llvm::DenseMap<const VarDecl*, unsigned> Visited;
|
||||
llvm::SmallSet<const DeclContext*, 4> IgnoredContexts;
|
||||
public:
|
||||
FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
|
||||
BumpVectorContext &bc)
|
||||
: BEVals(bevals), BC(bc) {}
|
||||
|
||||
|
||||
bool IsTrackedDecl(const VarDecl *VD) {
|
||||
const DeclContext *DC = VD->getDeclContext();
|
||||
return IgnoredContexts.count(DC) == 0;
|
||||
}
|
||||
|
||||
void VisitStmt(Stmt *S) {
|
||||
for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();I!=E;++I)
|
||||
if (Stmt *child = *I)
|
||||
@@ -229,16 +236,23 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VisitBlockDeclRefExpr(BlockDeclRefExpr *DR) {
|
||||
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
|
||||
unsigned &flag = Visited[VD];
|
||||
if (!flag) {
|
||||
flag = 1;
|
||||
BEVals.push_back(VD, BC);
|
||||
if (IsTrackedDecl(VD))
|
||||
BEVals.push_back(VD, BC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VisitBlockExpr(BlockExpr *BR) {
|
||||
// Blocks containing blocks can transitively capture more variables.
|
||||
IgnoredContexts.insert(BR->getBlockDecl());
|
||||
Visit(BR->getBlockDecl()->getBody());
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
|
||||
// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
|
||||
|
||||
void f1() {
|
||||
int k, y;
|
||||
@@ -377,7 +377,7 @@ void f24_A(int y) {
|
||||
// FIXME: One day this should be reported as dead since 'z = x + y' is dead.
|
||||
int x = (y > 2); // no-warning
|
||||
^ {
|
||||
int z = x + y; // FIXME: Eventually this should be reported as a dead store.
|
||||
int z = x + y; // expected-warning{{Value stored to 'z' during its initialization is never read}}
|
||||
}();
|
||||
}
|
||||
|
||||
@@ -429,3 +429,17 @@ int f25_b(int y) {
|
||||
return z;
|
||||
}
|
||||
|
||||
int f26_nestedblocks() {
|
||||
int z;
|
||||
z = 1;
|
||||
__block int y = 0;
|
||||
^{
|
||||
int k;
|
||||
k = 1; // expected-warning{{Value stored to 'k' is never read}}
|
||||
^{
|
||||
y = z + 1;
|
||||
}();
|
||||
}();
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user