[cfe-commits] r42055 - in /cfe/trunk: Analysis/DataflowSolver.h Analysis/UnintializedValues.cpp Driver/ASTStreamers.cpp Driver/ASTStreamers.h Driver/clang.cpp include/clang/Analysis/CFGVarDeclVisitor.h include/clang/Analysis/UninitializedValues.h
Ted Kremenek
kremenek at apple.com
Mon Sep 17 13:49:30 PDT 2007
Author: kremenek
Date: Mon Sep 17 15:49:30 2007
New Revision: 42055
URL: http://llvm.org/viewvc/llvm-project?rev=42055&view=rev
Log:
UninitialuzedValues now only tracks BlockVarDecls; obviating false positives with
globals and function parameters.
Modified:
cfe/trunk/Analysis/DataflowSolver.h
cfe/trunk/Analysis/UnintializedValues.cpp
cfe/trunk/Driver/ASTStreamers.cpp
cfe/trunk/Driver/ASTStreamers.h
cfe/trunk/Driver/clang.cpp
cfe/trunk/include/clang/Analysis/CFGVarDeclVisitor.h
cfe/trunk/include/clang/Analysis/UninitializedValues.h
Modified: cfe/trunk/Analysis/DataflowSolver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/DataflowSolver.h?rev=42055&r1=42054&r2=42055&view=diff
==============================================================================
--- cfe/trunk/Analysis/DataflowSolver.h (original)
+++ cfe/trunk/Analysis/DataflowSolver.h Mon Sep 17 15:49:30 2007
@@ -117,7 +117,15 @@
for (CFGBlock::const_succ_iterator I=B->succ_begin(), E=B->succ_end();
I != E; ++I)
WorkList.enqueue(*I);
- }
+ }
+
+ // For blocks that have no associated dataflow value, instantiate a
+ // default value.
+ BlockDataMapTy& M = D.getBlockDataMap();
+
+ for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
+ if (M.find(&*I) == M.end())
+ M[&*I].resetValues(D.getAnalysisData());
}
/// SolveDataflowEquations (BACKWARD ANALYSIS) - Perform the actual
@@ -153,7 +161,7 @@
ValTy& V = TF.getVal();
// Merge dataflow values from all predecessors of this block.
- V.resetValues();
+ V.resetValues(D.getAnalysisData());
MergeOperatorTy Merge;
for (CFGBlock::const_pred_iterator I=B->pred_begin(),
@@ -175,7 +183,7 @@
ValTy& V = TF.getVal();
// Merge dataflow values from all predecessors of this block.
- V.resetValues();
+ V.resetValues(D.getAnalysisData());
MergeOperatorTy Merge;
for (CFGBlock::const_succ_iterator I=B->succ_begin(),
Modified: cfe/trunk/Analysis/UnintializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/UnintializedValues.cpp?rev=42055&r1=42054&r2=42055&view=diff
==============================================================================
--- cfe/trunk/Analysis/UnintializedValues.cpp (original)
+++ cfe/trunk/Analysis/UnintializedValues.cpp Mon Sep 17 15:49:30 2007
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/UninitializedValues.h"
-#include "clang/Analysis/CFGVarDeclVisitor.h"
#include "clang/Analysis/CFGStmtVisitor.h"
#include "clang/Analysis/LocalCheckers.h"
#include "clang/Basic/Diagnostic.h"
@@ -29,32 +28,55 @@
namespace {
-class RegisterDeclsAndExprs : public CFGVarDeclVisitor<RegisterDeclsAndExprs> {
+class RegisterDeclsAndExprs : public CFGStmtVisitor<RegisterDeclsAndExprs> {
UninitializedValues::AnalysisDataTy& AD;
public:
- RegisterDeclsAndExprs(const CFG& cfg, UninitializedValues::AnalysisDataTy& ad)
- : CFGVarDeclVisitor<RegisterDeclsAndExprs>(cfg), AD(ad)
- {}
-
- void VisitVarDecl(VarDecl* D) {
- if (AD.VMap.find(D) == AD.VMap.end())
- AD.VMap[D] = AD.NumDecls++;
+ RegisterDeclsAndExprs(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
+
+ void VisitBlockVarDecl(BlockVarDecl* VD) {
+ if (AD.VMap.find(VD) == AD.VMap.end())
+ AD.VMap[VD] = AD.NumDecls++;
+ }
+
+ void VisitDeclChain(ScopedDecl* D) {
+ for (; D != NULL; D = D->getNextDeclarator())
+ if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(D))
+ VisitBlockVarDecl(VD);
}
void BlockStmt_VisitExpr(Expr* E) {
if (AD.EMap.find(E) == AD.EMap.end())
AD.EMap[E] = AD.NumBlockExprs++;
- }
+
+ Visit(E);
+ }
+
+ void VisitDeclRefExpr(DeclRefExpr* DR) {
+ VisitDeclChain(DR->getDecl());
+ }
+
+ void VisitDeclStmt(DeclStmt* S) {
+ VisitDeclChain(S->getDecl());
+ }
+
+ void VisitStmt(Stmt* S) {
+ VisitChildren(S);
+ }
+
};
} // end anonymous namespace
void UninitializedValues::InitializeValues(const CFG& cfg) {
- RegisterDeclsAndExprs R(cfg,this->getAnalysisData());
- R.VisitAllDecls();
+ RegisterDeclsAndExprs R(this->getAnalysisData());
+
+ for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
+ for (CFGBlock::const_iterator BI=I->begin(), BE=I->end(); BI!=BE; ++BI)
+ R.BlockStmt_Visit(*BI);
+
+ // Initialize the values of the last block.
UninitializedValues::ValTy& V = getBlockDataMap()[&cfg.getEntry()];
- V.DeclBV.resize(getAnalysisData().NumDecls);
- V.ExprBV.resize(getAnalysisData().NumBlockExprs);
+ V.resetValues(getAnalysisData());
}
//===----------------------------------------------------------------------===//
@@ -68,8 +90,7 @@
UninitializedValues::AnalysisDataTy& AD;
public:
TransferFuncs(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {
- V.DeclBV.resize(AD.NumDecls);
- V.ExprBV.resize(AD.NumBlockExprs);
+ V.resetValues(AD);
}
UninitializedValues::ValTy& getVal() { return V; }
@@ -88,7 +109,7 @@
bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
+ if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl())) {
assert ( AD.VMap.find(VD) != AD.VMap.end() && "Unknown VarDecl.");
if (AD.Observer)
AD.Observer->ObserveDeclRefExpr(V,AD,DR,VD);
@@ -111,7 +132,7 @@
if (ParenExpr* P = dyn_cast<ParenExpr>(S))
S = P->getSubExpr();
else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
+ if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl())) {
assert ( AD.VMap.find(VD) != AD.VMap.end() && "Unknown VarDecl.");
return V.DeclBV[ AD.VMap[VD] ] = Visit(B->getRHS());
}
@@ -127,10 +148,13 @@
bool x = Initialized();
for (ScopedDecl* D = S->getDecl(); D != NULL; D = D->getNextDeclarator())
- if (VarDecl* VD = dyn_cast<VarDecl>(D))
+ if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(D))
if (Stmt* I = VD->getInit()) {
+ assert ( AD.EMap.find(cast<Expr>(I)) !=
+ AD.EMap.end() && "Unknown Expr.");
+
assert ( AD.VMap.find(VD) != AD.VMap.end() && "Unknown VarDecl.");
- x = V.DeclBV[ AD.VMap[VD] ] = Visit(I);
+ x = V.DeclBV[ AD.VMap[VD] ] = V.ExprBV[ AD.EMap[cast<Expr>(I)] ];
}
return x;
@@ -150,7 +174,7 @@
if (ParenExpr* P = dyn_cast<ParenExpr>(S))
S = P->getSubExpr();
else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) {
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
+ if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl())) {
assert ( AD.VMap.find(VD) != AD.VMap.end() && "Unknown VarDecl.");
V.DeclBV[ AD.VMap[VD] ] = Initialized();
}
@@ -222,7 +246,7 @@
assert (Dst.ExprBV.size() == Src.ExprBV.size()
&& "Bitvector sizes do not match.");
- Dst.ExprBV &= Src.ExprBV;
+ Dst.ExprBV |= Src.ExprBV;
}
};
} // end anonymous namespace
@@ -238,7 +262,7 @@
class UninitializedValuesChecker : public UninitializedValues::ObserverTy {
ASTContext &Ctx;
Diagnostic &Diags;
- llvm::SmallPtrSet<VarDecl*,10> AlreadyWarned;
+ llvm::SmallPtrSet<BlockVarDecl*,10> AlreadyWarned;
public:
UninitializedValuesChecker(ASTContext &ctx, Diagnostic &diags)
@@ -246,7 +270,7 @@
virtual void ObserveDeclRefExpr(UninitializedValues::ValTy& V,
UninitializedValues::AnalysisDataTy& AD,
- DeclRefExpr* DR, VarDecl* VD) {
+ DeclRefExpr* DR, BlockVarDecl* VD) {
assert ( AD.VMap.find(VD) != AD.VMap.end() && "Unknown VarDecl.");
if (V.DeclBV[ AD.VMap[VD] ] == TransferFuncs::Uninitialized())
@@ -257,6 +281,7 @@
} // end anonymous namespace
+namespace clang {
void CheckUninitializedValues(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags) {
@@ -274,3 +299,5 @@
for (CFG::iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
S.runOnBlock(&*I);
}
+
+}
Modified: cfe/trunk/Driver/ASTStreamers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTStreamers.cpp?rev=42055&r1=42054&r2=42055&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTStreamers.cpp (original)
+++ cfe/trunk/Driver/ASTStreamers.cpp Mon Sep 17 15:49:30 2007
@@ -210,7 +210,7 @@
}
//===----------------------------------------------------------------------===//
-// RunDeadStores - run checker to locate dead stores in a function
+// DeadStores - run checker to locate dead stores in a function
namespace {
class DeadStoreVisitor : public CFGVisitor {
@@ -232,6 +232,29 @@
}
//===----------------------------------------------------------------------===//
+// Unitialized Values - run checker to flag potential uses of uninitalized
+// variables.
+
+namespace {
+ class UninitValsVisitor : public CFGVisitor {
+ Diagnostic &Diags;
+ ASTContext *Ctx;
+ public:
+ UninitValsVisitor(Diagnostic &diags) : Diags(diags) {}
+ virtual void Initialize(ASTContext &Context, unsigned MainFileID) {
+ Ctx = &Context;
+ }
+
+ virtual void VisitCFG(CFG& C) { CheckUninitializedValues(C, *Ctx, Diags); }
+ virtual bool printFuncDeclStart() { return false; }
+ };
+} // end anonymous namespace
+
+ASTConsumer *clang::CreateUnitValsChecker(Diagnostic &Diags) {
+ return new UninitValsVisitor(Diags);
+}
+
+//===----------------------------------------------------------------------===//
// LLVM Emitter
#include "clang/Basic/Diagnostic.h"
Modified: cfe/trunk/Driver/ASTStreamers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTStreamers.h?rev=42055&r1=42054&r2=42055&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTStreamers.h (original)
+++ cfe/trunk/Driver/ASTStreamers.h Mon Sep 17 15:49:30 2007
@@ -24,6 +24,7 @@
ASTConsumer *CreateCFGDumper(bool ViewGraphs = false);
ASTConsumer *CreateLiveVarAnalyzer();
ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags);
+ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
ASTConsumer *CreateLLVMEmitter(Diagnostic &Diags);
} // end clang namespace
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=42055&r1=42054&r2=42055&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Mon Sep 17 15:49:30 2007
@@ -58,6 +58,7 @@
ParseCFGView, // Parse ASTS. Build CFGs. View CFGs.
AnalysisLiveVariables, // Print results of live-variable analysis.
WarnDeadStores, // Run DeadStores checker on parsed ASTs.
+ WarnUninitVals, // Run UnitializedVariables checker.
ParsePrintCallbacks, // Parse and print each callback.
ParseSyntaxOnly, // Parse and perform semantic analysis.
ParseNoop, // Parse with noop callbacks.
@@ -98,6 +99,8 @@
"Print results of live variable analysis."),
clEnumValN(WarnDeadStores, "check-dead-stores",
"Flag warnings of stores to dead variables."),
+ clEnumValN(WarnUninitVals, "check-unit-vals",
+ "Flag warnings of uses of unitialized variables."),
clEnumValN(EmitLLVM, "emit-llvm",
"Build ASTs then convert to LLVM, emit .ll file"),
clEnumValEnd));
@@ -870,6 +873,11 @@
ParseAST(PP, MainFileID, *C.get(), Stats);
break;
}
+ case WarnUninitVals: {
+ std::auto_ptr<ASTConsumer> C(CreateUnitValsChecker(PP.getDiagnostics()));
+ ParseAST(PP, MainFileID, *C.get(), Stats);
+ break;
+ }
case EmitLLVM: {
std::auto_ptr<ASTConsumer> C(CreateLLVMEmitter(PP.getDiagnostics()));
ParseAST(PP, MainFileID, *C.get(), Stats);
Modified: cfe/trunk/include/clang/Analysis/CFGVarDeclVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFGVarDeclVisitor.h?rev=42055&r1=42054&r2=42055&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFGVarDeclVisitor.h (original)
+++ cfe/trunk/include/clang/Analysis/CFGVarDeclVisitor.h Mon Sep 17 15:49:30 2007
@@ -29,8 +29,7 @@
CFGVarDeclVisitor(const CFG& c) : cfg(c) {}
void VisitStmt(Stmt* S) {
- for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
- static_cast<ImplClass*>(this)->Visit(*I);
+ static_cast<ImplClass*>(this)->VisitChildren(S);
}
void VisitDeclRefExpr(DeclRefExpr* DR) {
@@ -56,7 +55,7 @@
void VisitAllDecls() {
for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI)
for (CFGBlock::const_iterator SI=BI->begin(),SE = BI->end();SI != SE;++SI)
- static_cast<ImplClass*>(this)->Visit(const_cast<Stmt*>(*SI));
+ static_cast<ImplClass*>(this)->BlockStmt_Visit(const_cast<Stmt*>(*SI));
}
};
Modified: cfe/trunk/include/clang/Analysis/UninitializedValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/UninitializedValues.h?rev=42055&r1=42054&r2=42055&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/UninitializedValues.h (original)
+++ cfe/trunk/include/clang/Analysis/UninitializedValues.h Mon Sep 17 15:49:30 2007
@@ -20,7 +20,7 @@
namespace clang {
- class VarDecl;
+ class BlockVarDecl;
class Expr;
class DeclRefExpr;
@@ -31,6 +31,23 @@
public:
//===--------------------------------------------------------------------===//
+ // AnalysisDataTy - Whole-function meta data used by the transfer function
+ // logic.
+ //===--------------------------------------------------------------------===//
+
+ struct ObserverTy;
+
+ struct AnalysisDataTy {
+ llvm::DenseMap<const BlockVarDecl*, unsigned > VMap;
+ llvm::DenseMap<const Expr*, unsigned > EMap;
+ unsigned NumDecls;
+ unsigned NumBlockExprs;
+ ObserverTy* Observer;
+
+ AnalysisDataTy() : NumDecls(0), NumBlockExprs(0), Observer(NULL) {}
+ };
+
+ //===--------------------------------------------------------------------===//
// ValTy - Dataflow value.
//===--------------------------------------------------------------------===//
@@ -38,9 +55,10 @@
llvm::BitVector DeclBV;
llvm::BitVector ExprBV;
- // Used by the solver.
- void resetValues() {
+ void resetValues(AnalysisDataTy& AD) {
+ DeclBV.resize(AD.NumDecls);
DeclBV.reset();
+ ExprBV.resize(AD.NumBlockExprs);
ExprBV.reset();
}
@@ -52,24 +70,7 @@
DeclBV = RHS.DeclBV;
ExprBV = RHS.ExprBV;
}
- };
-
- //===--------------------------------------------------------------------===//
- // AnalysisDataTy - Whole-function meta data used by the transfer function
- // logic.
- //===--------------------------------------------------------------------===//
-
- struct ObserverTy;
-
- struct AnalysisDataTy {
- llvm::DenseMap<const VarDecl*, unsigned > VMap;
- llvm::DenseMap<const Expr*, unsigned > EMap;
- unsigned NumDecls;
- unsigned NumBlockExprs;
- ObserverTy* Observer;
-
- AnalysisDataTy() : NumDecls(0), NumBlockExprs(0), Observer(NULL) {}
- };
+ };
//===--------------------------------------------------------------------===//
// ObserverTy - Observer for querying DeclRefExprs that use an uninitalized
@@ -79,7 +80,7 @@
struct ObserverTy {
virtual ~ObserverTy();
virtual void ObserveDeclRefExpr(ValTy& Val, AnalysisDataTy& AD,
- DeclRefExpr* DR, VarDecl* VD) = 0;
+ DeclRefExpr* DR, BlockVarDecl* VD) = 0;
};
};
More information about the cfe-commits
mailing list