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