2007-09-14 22:49:21 +00:00
|
|
|
//==- 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 {
|
|
|
|
|
2007-09-17 17:14:52 +00:00
|
|
|
class RegisterDeclsAndExprs : public CFGVarDeclVisitor<RegisterDeclsAndExprs> {
|
|
|
|
UninitializedValues::AnalysisDataTy& AD;
|
2007-09-14 22:49:21 +00:00
|
|
|
public:
|
2007-09-17 17:14:52 +00:00
|
|
|
RegisterDeclsAndExprs(const CFG& cfg, UninitializedValues::AnalysisDataTy& ad)
|
|
|
|
: CFGVarDeclVisitor<RegisterDeclsAndExprs>(cfg), AD(ad)
|
|
|
|
{}
|
2007-09-14 22:49:21 +00:00
|
|
|
|
|
|
|
void VisitVarDecl(VarDecl* D) {
|
2007-09-17 17:14:52 +00:00
|
|
|
if (AD.VMap.find(D) == AD.VMap.end())
|
|
|
|
AD.VMap[D] = AD.Counter++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BlockStmt_VisitExpr(Expr* E) {
|
|
|
|
if (AD.EMap.find(E) == AD.EMap.end())
|
|
|
|
AD.EMap[E] = AD.Counter++;
|
|
|
|
}
|
2007-09-14 22:49:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
void UninitializedValues::InitializeValues(const CFG& cfg) {
|
2007-09-17 17:14:52 +00:00
|
|
|
RegisterDeclsAndExprs R(cfg,this->getAnalysisData());
|
|
|
|
R.VisitAllDecls();
|
|
|
|
getBlockDataMap()[ &cfg.getEntry() ].resize( getAnalysisData().Counter );
|
2007-09-14 22:49:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Transfer functions.
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
class TransferFuncs : public CFGStmtVisitor<TransferFuncs,bool> {
|
|
|
|
UninitializedValues::ValTy V;
|
2007-09-17 17:14:52 +00:00
|
|
|
UninitializedValues::AnalysisDataTy& AD;
|
2007-09-14 22:49:21 +00:00
|
|
|
public:
|
2007-09-17 17:14:52 +00:00
|
|
|
TransferFuncs(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {
|
|
|
|
V.resize(AD.Counter);
|
2007-09-14 22:49:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UninitializedValues::ValTy& getVal() { return V; }
|
2007-09-17 17:14:52 +00:00
|
|
|
|
|
|
|
// bool VisitDeclRefExpr(DeclRefExpr* DR);
|
|
|
|
// bool VisitBinaryOperator(BinaryOperator* B);
|
|
|
|
// bool VisitUnaryOperator(UnaryOperator* U);
|
2007-09-14 22:49:21 +00:00
|
|
|
};
|
|
|
|
} // 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);
|
|
|
|
}
|