[cfe-commits] r42109 - in /cfe/trunk: Analysis/UninitializedValues.cpp include/clang/Analysis/UninitializedValues.h
Ted Kremenek
kremenek at apple.com
Tue Sep 18 14:43:18 PDT 2007
Author: kremenek
Date: Tue Sep 18 16:43:18 2007
New Revision: 42109
URL: http://llvm.org/viewvc/llvm-project?rev=42109&view=rev
Log:
More refactoring and code reduction.
Modified:
cfe/trunk/Analysis/UninitializedValues.cpp
cfe/trunk/include/clang/Analysis/UninitializedValues.h
Modified: cfe/trunk/Analysis/UninitializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/UninitializedValues.cpp?rev=42109&r1=42108&r2=42109&view=diff
==============================================================================
--- cfe/trunk/Analysis/UninitializedValues.cpp (original)
+++ cfe/trunk/Analysis/UninitializedValues.cpp Tue Sep 18 16:43:18 2007
@@ -91,6 +91,8 @@
bool BlockStmt_VisitExpr(Expr* E);
bool VisitDeclStmt(DeclStmt* D);
+ BlockVarDecl* FindBlockVarDecl(Stmt* S);
+
static inline bool Initialized() { return true; }
static inline bool Uninitialized() { return false; }
};
@@ -98,48 +100,47 @@
bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
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);
+ if (AD.Observer) AD.Observer->ObserveDeclRefExpr(V,AD,DR,VD);
- return V.DeclBV[ AD.VMap[VD] ];
+ return V.getBitRef(VD,AD);
}
- else
- return Initialized();
+ else return Initialized();
+}
+
+BlockVarDecl* TransferFuncs::FindBlockVarDecl(Stmt *S) {
+ for (;;) {
+ if (ParenExpr* P = dyn_cast<ParenExpr>(S)) {
+ S = P->getSubExpr();
+ continue;
+ }
+ else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
+ if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl()))
+ return VD;
+
+ return NULL;
+ }
}
bool TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
- if (CFG::hasImplicitControlFlow(B)) {
- assert ( AD.EMap.find(B) != AD.EMap.end() && "Unknown block-level expr.");
- return V.ExprBV[ AD.EMap[B] ];
- }
-
- if (B->isAssignmentOp()) {
- // Get the Decl for the LHS, if any
- for (Stmt* S = B->getLHS() ;; ) {
- if (ParenExpr* P = dyn_cast<ParenExpr>(S))
- S = P->getSubExpr();
- else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
- if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl())) {
- assert ( AD.VMap.find(VD) != AD.VMap.end() && "Unknown VarDecl.");
-
- if(InitWithAssigns) {
- // Pseudo-hack to prevent cascade of warnings. If the RHS uses
- // an uninitialized value, then we are already going to flag a warning
- // related to the "cause". Thus, propogating uninitialized doesn't
- // make sense, since we are just adding extra messages that don't
- // contribute to diagnosing the bug. In InitWithAssigns mode
- // we unconditionally set the assigned variable to Initialized to
- // prevent Uninitialized propogation.
- return V.DeclBV[AD.VMap[VD]] = Initialized();
- }
- else
- return V.DeclBV[ AD.VMap[VD] ] = Visit(B->getRHS());
- }
- break;
- }
- }
+ if (CFG::hasImplicitControlFlow(B))
+ return V.getBitRef(B,AD);
+
+ if (B->isAssignmentOp())
+ // Get the Decl for the LHS (if any).
+ if (BlockVarDecl* VD = FindBlockVarDecl(B->getLHS()))
+ if(InitWithAssigns) {
+ // Pseudo-hack to prevent cascade of warnings. If the RHS uses
+ // an uninitialized value, then we are already going to flag a warning
+ // for the RHS, or for the root "source" of the unintialized values.
+ // Thus, propogating uninitialized doesn't make sense, since we are
+ // just adding extra messages that don't
+ // contribute to diagnosing the bug. In InitWithAssigns mode
+ // we unconditionally set the assigned variable to Initialized to
+ // prevent Uninitialized propogation.
+ return V.getBitRef(VD,AD) = Initialized();
+ }
+ else return V.getBitRef(VD,AD) = Visit(B->getRHS());
return VisitStmt(B);
}
@@ -150,12 +151,8 @@
for (ScopedDecl* D = S->getDecl(); D != NULL; D = D->getNextDeclarator())
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.ExprBV[ AD.EMap[cast<Expr>(I)] ];
- V.DeclBV[ AD.VMap[VD] ] = x;
+ x = V.getBitRef(cast<Expr>(I),AD);
+ V.getBitRef(VD,AD) = x;
}
return x;
@@ -168,27 +165,12 @@
bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
switch (U->getOpcode()) {
- case UnaryOperator::AddrOf: {
- // Blast through parentheses and find the decl (if any). Treat it
- // as initialized from this point forward.
- for (Stmt* S = U->getSubExpr() ;; )
- if (ParenExpr* P = dyn_cast<ParenExpr>(S))
- S = P->getSubExpr();
- else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) {
- if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl())) {
- assert ( AD.VMap.find(VD) != AD.VMap.end() && "Unknown VarDecl.");
- V.DeclBV[ AD.VMap[VD] ] = Initialized();
- }
- break;
- }
- else {
- // Evaluate the transfer function for subexpressions, even
- // if we cannot reason more deeply about the &-expression.
- return Visit(U->getSubExpr());
- }
-
- return Initialized();
- }
+ case UnaryOperator::AddrOf:
+ // For "&x", treat "x" as now being initialized.
+ if (BlockVarDecl* VD = FindBlockVarDecl(U->getSubExpr()))
+ V.getBitRef(VD,AD) = Initialized();
+ else
+ return Visit(U->getSubExpr());
default:
return Visit(U->getSubExpr());
@@ -202,15 +184,14 @@
// evaluating some subexpressions may result in propogating "Uninitialized"
// or "Initialized" to variables referenced in the other subexpressions.
for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
- if (Visit(*I) == Uninitialized())
- x = Uninitialized();
+ if (Visit(*I) == Uninitialized()) x = Uninitialized();
return x;
}
bool TransferFuncs::BlockStmt_VisitExpr(Expr* E) {
- assert ( AD.EMap.find(E) != AD.EMap.end() );
- return V.ExprBV[ AD.EMap[E] ] = Visit(E);
+ assert (AD.isTracked(E));
+ return V.getBitRef(E,AD) = Visit(E);
}
} // end anonymous namespace
@@ -233,9 +214,7 @@
struct Merge {
void operator()(UninitializedValues::ValTy& Dst,
UninitializedValues::ValTy& Src) {
- assert (Dst.DeclBV.size() == Src.DeclBV.size() && "BV sizes do not match.");
- assert (Dst.ExprBV.size() == Src.ExprBV.size() && "BV sizes do not match.");
-
+ assert (Src.sizesEqual(Dst) && "BV sizes do not match.");
Dst.DeclBV |= Src.DeclBV;
Dst.ExprBV |= Src.ExprBV;
}
@@ -262,8 +241,9 @@
UninitializedValues::AnalysisDataTy& AD,
DeclRefExpr* DR, BlockVarDecl* VD) {
- assert ( AD.VMap.find(VD) != AD.VMap.end() && "Unknown VarDecl.");
- if (V.DeclBV[ AD.VMap[VD] ] == TransferFuncs::Uninitialized())
+ assert ( AD.isTracked(VD) && "Unknown VarDecl.");
+
+ if (V.getBitRef(VD,AD) == TransferFuncs::Uninitialized())
if (AlreadyWarned.insert(VD))
Diags.Report(DR->getSourceRange().Begin(), diag::warn_uninit_val);
}
Modified: cfe/trunk/include/clang/Analysis/UninitializedValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/UninitializedValues.h?rev=42109&r1=42108&r2=42109&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/UninitializedValues.h (original)
+++ cfe/trunk/include/clang/Analysis/UninitializedValues.h Tue Sep 18 16:43:18 2007
@@ -23,7 +23,8 @@
class BlockVarDecl;
class Expr;
class DeclRefExpr;
-
+ class VarDecl;
+
/// UninitializedValues_ValueTypes - Utility class to wrap type declarations
/// for dataflow values and dataflow analysis state for the
/// Unitialized Values analysis.
@@ -45,6 +46,14 @@
ObserverTy* Observer;
AnalysisDataTy() : NumDecls(0), NumBlockExprs(0), Observer(NULL) {}
+
+ bool isTracked(const BlockVarDecl* VD) {
+ return VMap.find(VD) != VMap.end();
+ }
+
+ bool isTracked(const Expr* E) {
+ return EMap.find(E) != EMap.end();
+ }
};
//===--------------------------------------------------------------------===//
@@ -69,7 +78,24 @@
void copyValues(ValTy& RHS) {
DeclBV = RHS.DeclBV;
ExprBV = RHS.ExprBV;
- }
+ }
+
+ llvm::BitVector::reference getBitRef(const BlockVarDecl* VD,
+ AnalysisDataTy& AD) {
+ assert (AD.isTracked(VD) && "BlockVarDecl not tracked.");
+ return DeclBV[AD.VMap[VD]];
+ }
+
+ llvm::BitVector::reference getBitRef(const Expr* E,
+ AnalysisDataTy& AD) {
+ assert (AD.isTracked(E) && "Expr not tracked.");
+ return DeclBV[AD.EMap[E]];
+ }
+
+ bool sizesEqual(ValTy& RHS) {
+ return DeclBV.size() == RHS.DeclBV.size() &&
+ ExprBV.size() == RHS.ExprBV.size();
+ }
};
//===--------------------------------------------------------------------===//
More information about the cfe-commits
mailing list