Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//==- UninitializedValues.cpp - Find Unintialized Values --------*- C++ --*-==//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Ted Kremenek and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Uninitialized Values analysis for source-level CFGs.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/UninitializedValues.h"
#include "clang/Analysis/CFGVarDeclVisitor.h"
#include "clang/Analysis/CFGStmtVisitor.h"
#include "DataflowSolver.h"
using namespace clang;
//===--------------------------------------------------------------------===//
// Dataflow initialization logic.
//===--------------------------------------------------------------------===//
namespace {
class RegisterDecls : public CFGVarDeclVisitor<RegisterDecls> {
UninitializedValues::MetaDataTy& M;
public:
RegisterDecls(const CFG& cfg, UninitializedValues::MetaDataTy& m) :
CFGVarDeclVisitor<RegisterDecls>(cfg), M(m) {}
void VisitVarDecl(VarDecl* D) {
if (M.Map.find(D) == M.Map.end()) {
M.Map[D] = M.NumDecls++;
}
}
};
} // end anonymous namespace
void UninitializedValues::InitializeValues(const CFG& cfg) {
RegisterDecls R(cfg,this->getMetaData());
R.VisitAllDecls();
getBlockDataMap()[ &cfg.getEntry() ].resize( getMetaData().NumDecls );
}
//===--------------------------------------------------------------------===//
// Transfer functions.
//===--------------------------------------------------------------------===//
namespace {
class TransferFuncs : public CFGStmtVisitor<TransferFuncs,bool> {
UninitializedValues::ValTy V;
UninitializedValues::MetaDataTy& M;
UninitializedValues::ObserverTy* O;
public:
TransferFuncs(UninitializedValues::MetaDataTy& m,
UninitializedValues::ObserverTy* o) : M(m), O(o) {
V.resize(M.NumDecls);
}
UninitializedValues::ValTy& getVal() { return V; }
};
} // end anonymous namespace
//===--------------------------------------------------------------------===//
// Merge operator.
//===--------------------------------------------------------------------===//
namespace {
struct Merge {
void operator()(UninitializedValues::ValTy& Dst,
UninitializedValues::ValTy& Src) {
assert (Dst.size() == Src.size() && "Bitvector sizes do not match.");
Src |= Dst;
}
};
} // end anonymous namespace
//===--------------------------------------------------------------------===//
// Observer to flag warnings for uses of uninitialized variables.
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
// External interface (driver logic).
//===--------------------------------------------------------------------===//
void UninitializedValues::CheckUninitializedValues(const CFG& cfg) {
typedef DataflowSolver<UninitializedValues,TransferFuncs,Merge> Solver;
UninitializedValues U;
{ // Compute the unitialized values information.
Solver S(U);
S.runOnCFG(cfg);
}
// WarnObserver O;
Solver S(U);
for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
S.runOnBlock(&*I);
}