summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/UninitializedValuesV2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/UninitializedValuesV2.cpp')
-rw-r--r--clang/lib/Analysis/UninitializedValuesV2.cpp39
1 files changed, 31 insertions, 8 deletions
diff --git a/clang/lib/Analysis/UninitializedValuesV2.cpp b/clang/lib/Analysis/UninitializedValuesV2.cpp
index 4c548854131..4edc1a965bd 100644
--- a/clang/lib/Analysis/UninitializedValuesV2.cpp
+++ b/clang/lib/Analysis/UninitializedValuesV2.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "clang/AST/Decl.h"
#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
#include "clang/Analysis/Analyses/UninitializedValuesV2.h"
#include "clang/Analysis/Support/SaveAndRestore.h"
@@ -287,16 +288,22 @@ public:
class TransferFunctions : public CFGRecStmtVisitor<TransferFunctions> {
CFGBlockValues &vals;
const CFG &cfg;
+ AnalysisContext &ac;
UninitVariablesHandler *handler;
const DeclRefExpr *currentDR;
+ const bool flagBlockUses;
public:
TransferFunctions(CFGBlockValues &vals, const CFG &cfg,
- UninitVariablesHandler *handler)
- : vals(vals), cfg(cfg), handler(handler), currentDR(0) {}
+ AnalysisContext &ac,
+ UninitVariablesHandler *handler,
+ bool flagBlockUses)
+ : vals(vals), cfg(cfg), ac(ac), handler(handler), currentDR(0),
+ flagBlockUses(flagBlockUses) {}
const CFG &getCFG() { return cfg; }
void reportUninit(const DeclRefExpr *ex, const VarDecl *vd);
-
+
+ void VisitBlockExpr(BlockExpr *be);
void VisitDeclStmt(DeclStmt *ds);
void VisitDeclRefExpr(DeclRefExpr *dr);
void VisitUnaryOperator(UnaryOperator *uo);
@@ -311,6 +318,20 @@ void TransferFunctions::reportUninit(const DeclRefExpr *ex,
if (handler) handler->handleUseOfUninitVariable(ex, vd);
}
+void TransferFunctions::VisitBlockExpr(BlockExpr *be) {
+ if (!flagBlockUses || !handler)
+ return;
+ AnalysisContext::referenced_decls_iterator i, e;
+ llvm::tie(i, e) = ac.getReferencedBlockVars(be->getBlockDecl());
+ for ( ; i != e; ++i) {
+ const VarDecl *vd = *i;
+ if (vd->getAttr<BlocksAttr>() || !vd->hasLocalStorage())
+ continue;
+ if (vals[vd] == Uninitialized)
+ handler->handleUseOfUninitVariable(be, vd);
+ }
+}
+
void TransferFunctions::VisitDeclStmt(DeclStmt *ds) {
for (DeclStmt::decl_iterator DI = ds->decl_begin(), DE = ds->decl_end();
DI != DE; ++DI) {
@@ -450,8 +471,9 @@ void TransferFunctions::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *se) {
//====------------------------------------------------------------------------//
static bool runOnBlock(const CFGBlock *block, const CFG &cfg,
- CFGBlockValues &vals,
- UninitVariablesHandler *handler = 0) {
+ AnalysisContext &ac, CFGBlockValues &vals,
+ UninitVariablesHandler *handler = 0,
+ bool flagBlockUses = false) {
if (const BinaryOperator *b = getLogicalOperatorInChain(block)) {
if (block->pred_size() == 2 && block->succ_size() == 2) {
@@ -478,7 +500,7 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg,
isFirst = false;
}
// Apply the transfer function.
- TransferFunctions tf(vals, cfg, handler);
+ TransferFunctions tf(vals, cfg, ac, handler, flagBlockUses);
for (CFGBlock::const_iterator I = block->begin(), E = block->end();
I != E; ++I) {
if (const CFGStmt *cs = dyn_cast<CFGStmt>(&*I)) {
@@ -490,6 +512,7 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg,
void clang::runUninitializedVariablesAnalysis(const DeclContext &dc,
const CFG &cfg,
+ AnalysisContext &ac,
UninitVariablesHandler &handler) {
CFGBlockValues vals(cfg);
vals.computeSetOfDeclarations(dc);
@@ -502,7 +525,7 @@ void clang::runUninitializedVariablesAnalysis(const DeclContext &dc,
while (const CFGBlock *block = worklist.dequeue()) {
// Did the block change?
- bool changed = runOnBlock(block, cfg, vals);
+ bool changed = runOnBlock(block, cfg, ac, vals);
if (changed || !previouslyVisited[block->getBlockID()])
worklist.enqueueSuccessors(block);
previouslyVisited[block->getBlockID()] = true;
@@ -510,7 +533,7 @@ void clang::runUninitializedVariablesAnalysis(const DeclContext &dc,
// Run through the blocks one more time, and report uninitialized variabes.
for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI) {
- runOnBlock(*BI, cfg, vals, &handler);
+ runOnBlock(*BI, cfg, ac, vals, &handler, /* flagBlockUses */ true);
}
}
OpenPOWER on IntegriCloud