[cfe-commits] r42408 - in /cfe/trunk: Analysis/UninitializedValues.cpp include/clang/Analysis/ExprDeclBitVector.h include/clang/Analysis/UninitializedValues.h include/clang/Basic/DiagnosticKinds.def
Ted Kremenek
kremenek at apple.com
Thu Sep 27 11:20:23 PDT 2007
Author: kremenek
Date: Thu Sep 27 13:20:22 2007
New Revision: 42408
URL: http://llvm.org/viewvc/llvm-project?rev=42408&view=rev
Log:
Created new "ExprDeclBitVector" type bundle for dataflow analyses that need boolean
values associated with ScopedDecls and CFGBlock-level Exprs. This is the common
boilerplate needed by UninitializedValues and LiveVariables.
Refactored UninitializedValues to use ExprDeclBitVector.
Shortened the string diagnostic for UninitializedValues.
Added:
cfe/trunk/include/clang/Analysis/ExprDeclBitVector.h
Modified:
cfe/trunk/Analysis/UninitializedValues.cpp
cfe/trunk/include/clang/Analysis/UninitializedValues.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/trunk/Analysis/UninitializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/UninitializedValues.cpp?rev=42408&r1=42407&r2=42408&view=diff
==============================================================================
--- cfe/trunk/Analysis/UninitializedValues.cpp (original)
+++ cfe/trunk/Analysis/UninitializedValues.cpp Thu Sep 27 13:20:22 2007
@@ -33,13 +33,8 @@
public:
RegisterDeclsExprs(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
- void VisitBlockVarDecl(BlockVarDecl* VD) {
- if (!AD.isTracked(VD)) AD[VD] = AD.NumDecls++;
- }
-
- void BlockStmt_VisitExpr(Expr* E) {
- if (!AD.isTracked(E)) AD[E] = AD.NumBlockExprs++;
- }
+ void VisitBlockVarDecl(BlockVarDecl* VD) { AD.Register(VD); }
+ void BlockStmt_VisitExpr(Expr* E) { AD.Register(E); }
};
} // end anonymous namespace
@@ -77,19 +72,19 @@
bool VisitDeclStmt(DeclStmt* D);
BlockVarDecl* FindBlockVarDecl(Stmt* S);
-
- static inline bool Initialized() { return true; }
- static inline bool Uninitialized() { return false; }
};
+
+static const bool Initialized = true;
+static const bool Uninitialized = false;
bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(DR->getDecl())) {
if (AD.Observer) AD.Observer->ObserveDeclRefExpr(V,AD,DR,VD);
- return V.getBitRef(VD,AD);
+ return V(VD,AD);
}
- else return Initialized();
+ else return Initialized;
}
BlockVarDecl* TransferFuncs::FindBlockVarDecl(Stmt *S) {
@@ -109,7 +104,7 @@
bool TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
if (CFG::hasImplicitControlFlow(B))
- return V.getBitRef(B,AD);
+ return V(B,AD);
if (B->isAssignmentOp())
// Get the Decl for the LHS (if any).
@@ -122,30 +117,33 @@
// 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();
+ // prevent Uninitialized propagation.
+ return V(VD,AD) = Initialized;
}
- else return V.getBitRef(VD,AD) = Visit(B->getRHS());
+ else return V(VD,AD) = Visit(B->getRHS());
return VisitStmt(B);
}
bool TransferFuncs::VisitDeclStmt(DeclStmt* S) {
- bool x = Initialized();
+ bool x = Initialized;
for (ScopedDecl* D = S->getDecl(); D != NULL; D = D->getNextDeclarator())
- if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(D))
- if (Stmt* I = VD->getInit()) {
- x = V.getBitRef(cast<Expr>(I),AD);
- V.getBitRef(VD,AD) = x;
- }
+ if (BlockVarDecl* VD = dyn_cast<BlockVarDecl>(D)) {
+ if (Stmt* I = VD->getInit())
+ x = InitWithAssigns ? Initialized : V(cast<Expr>(I),AD);
+ else
+ x = Uninitialized;
+
+ V(VD,AD) = x;
+ }
return x;
}
bool TransferFuncs::VisitCallExpr(CallExpr* C) {
VisitChildren(C);
- return Initialized();
+ return Initialized;
}
bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
@@ -153,7 +151,7 @@
case UnaryOperator::AddrOf:
// For "&x", treat "x" as now being initialized.
if (BlockVarDecl* VD = FindBlockVarDecl(U->getSubExpr()))
- V.getBitRef(VD,AD) = Initialized();
+ V(VD,AD) = Initialized;
else
return Visit(U->getSubExpr());
@@ -163,20 +161,20 @@
}
bool TransferFuncs::VisitStmt(Stmt* S) {
- bool x = Initialized();
+ bool x = Initialized;
// We don't stop at the first subexpression that is Uninitialized because
// 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.isTracked(E));
- return V.getBitRef(E,AD) = Visit(E);
+ return V(E,AD) = Visit(E);
}
} // end anonymous namespace
@@ -196,15 +194,9 @@
//===----------------------------------------------------------------------===//
namespace {
-struct Merge {
- void operator()(UninitializedValues::ValTy& Dst,
- UninitializedValues::ValTy& Src) {
- assert (Src.sizesEqual(Dst) && "BV sizes do not match.");
- Dst.DeclBV |= Src.DeclBV;
- Dst.ExprBV |= Src.ExprBV;
- }
-};
-} // end anonymous namespace
+ typedef ExprDeclBitVector_Types::Union Merge;
+ typedef DataflowSolver<UninitializedValues,TransferFuncs,Merge> Solver;
+}
//===----------------------------------------------------------------------===//
// Unitialized values checker. Scan an AST and flag variable uses
@@ -228,7 +220,7 @@
assert ( AD.isTracked(VD) && "Unknown VarDecl.");
- if (V.getBitRef(VD,AD) == TransferFuncs::Uninitialized())
+ if (V(VD,AD) == Uninitialized)
if (AlreadyWarned.insert(VD))
Diags.Report(DR->getSourceRange().Begin(), diag::warn_uninit_val);
}
@@ -237,8 +229,6 @@
namespace clang {
void CheckUninitializedValues(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags) {
-
- typedef DataflowSolver<UninitializedValues,TransferFuncs,Merge> Solver;
// Compute the unitialized values information.
UninitializedValues U;
Added: cfe/trunk/include/clang/Analysis/ExprDeclBitVector.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ExprDeclBitVector.h?rev=42408&view=auto
==============================================================================
--- cfe/trunk/include/clang/Analysis/ExprDeclBitVector.h (added)
+++ cfe/trunk/include/clang/Analysis/ExprDeclBitVector.h Thu Sep 27 13:20:22 2007
@@ -0,0 +1,149 @@
+//=- ExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- 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 provides definition of dataflow types used by analyses such
+// as LiveVariables and UninitializedValues. The underlying dataflow values
+// are implemented as bitvectors, but the definitions in this file include
+// the necessary boilerplate to use with our dataflow framework.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXPRDECLBVDVAL_H
+#define LLVM_CLANG_EXPRDECLBVDVAL_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+ class Expr;
+ class ScopedDecl;
+
+struct ExprDeclBitVector_Types {
+
+ //===--------------------------------------------------------------------===//
+ // AnalysisDataTy - Whole-function meta data.
+ //===--------------------------------------------------------------------===//
+
+ class AnalysisDataTy {
+ typedef llvm::DenseMap<const ScopedDecl*, unsigned > DMapTy;
+ typedef llvm::DenseMap<const Expr*, unsigned > EMapTy;
+
+ EMapTy EMap;
+ DMapTy DMap;
+ unsigned NDecls;
+ unsigned NExprs;
+
+ public:
+
+ AnalysisDataTy() : NDecls(0), NExprs(0) {}
+ virtual ~AnalysisDataTy() {}
+
+ bool isTracked(const ScopedDecl* SD) { return DMap.find(SD) != DMap.end(); }
+ bool isTracked(const Expr* E) { return EMap.find(E) != EMap.end(); }
+
+ unsigned operator[](const ScopedDecl* SD) const {
+ DMapTy::const_iterator I = DMap.find(SD);
+ assert (I != DMap.end());
+ return I->second;
+ }
+
+ unsigned operator[](const Expr* E) const {
+ EMapTy::const_iterator I = EMap.find(E);
+ assert (I != EMap.end());
+ return I->second;
+ }
+
+ unsigned getNumDecls() const { return NDecls; }
+ unsigned getNumExprs() const { return NExprs; }
+
+ void Register(const ScopedDecl* SD) {
+ if (!isTracked(SD)) DMap[SD] = NDecls++;
+ }
+
+ void Register(const Expr* E) {
+ if (!isTracked(E)) EMap[E] = NExprs++;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ // ValTy - Dataflow value.
+ //===--------------------------------------------------------------------===//
+
+ class ValTy {
+ llvm::BitVector DeclBV;
+ llvm::BitVector ExprBV;
+ public:
+
+ void resetValues(AnalysisDataTy& AD) {
+ DeclBV.resize(AD.getNumDecls());
+ DeclBV.reset();
+ ExprBV.resize(AD.getNumExprs());
+ ExprBV.reset();
+ }
+
+ bool operator==(const ValTy& RHS) const {
+ assert (sizesEqual(RHS));
+ return DeclBV == RHS.DeclBV && ExprBV == RHS.ExprBV;
+ }
+
+ void copyValues(const ValTy& RHS) {
+ DeclBV = RHS.DeclBV;
+ ExprBV = RHS.ExprBV;
+ }
+
+ llvm::BitVector::reference
+ operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) {
+ return DeclBV[AD[SD]];
+ }
+ const llvm::BitVector::reference
+ operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) const {
+ return const_cast<ValTy&>(*this)(SD,AD);
+ }
+
+ llvm::BitVector::reference
+ operator()(const Expr* E, const AnalysisDataTy& AD) {
+ return ExprBV[AD[E]];
+ }
+ const llvm::BitVector::reference
+ operator()(const Expr* E, const AnalysisDataTy& AD) const {
+ return const_cast<ValTy&>(*this)(E,AD);
+ }
+
+ ValTy& operator|=(const ValTy& RHS) {
+ assert (sizesEqual(RHS));
+ DeclBV |= RHS.DeclBV;
+ ExprBV |= RHS.ExprBV;
+ return *this;
+ }
+
+ ValTy& operator&=(const ValTy& RHS) {
+ assert (sizesEqual(RHS));
+ DeclBV &= RHS.DeclBV;
+ ExprBV &= RHS.ExprBV;
+ return *this;
+ }
+
+ bool sizesEqual(const ValTy& RHS) const {
+ return DeclBV.size() == RHS.DeclBV.size()
+ && ExprBV.size() == RHS.ExprBV.size();
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ // Some useful merge operations.
+ //===--------------------------------------------------------------------===//
+
+ struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
+ struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
+
+};
+} // end namespace clang
+
+#endif
Modified: cfe/trunk/include/clang/Analysis/UninitializedValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/UninitializedValues.h?rev=42408&r1=42407&r2=42408&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/UninitializedValues.h (original)
+++ cfe/trunk/include/clang/Analysis/UninitializedValues.h Thu Sep 27 13:20:22 2007
@@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_UNITVALS_H
#define LLVM_CLANG_UNITVALS_H
-#include "llvm/ADT/BitVector.h"
+#include "clang/Analysis/ExprDeclBitVector.h"
#include "clang/Analysis/FlowSensitive/DataflowValues.h"
namespace clang {
@@ -31,75 +31,16 @@
class UninitializedValues_ValueTypes {
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;
+ struct AnalysisDataTy : public ExprDeclBitVector_Types::AnalysisDataTy {
+ AnalysisDataTy() : Observer(NULL) {}
+ virtual ~AnalysisDataTy() {};
- 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();
- }
-
- unsigned& operator[](const BlockVarDecl *VD) { return VMap[VD]; }
- unsigned& operator[](const Expr* E) { return EMap[E]; }
+ ObserverTy* Observer;
};
-
- //===--------------------------------------------------------------------===//
- // ValTy - Dataflow value.
- //===--------------------------------------------------------------------===//
- struct ValTy {
- llvm::BitVector DeclBV;
- llvm::BitVector ExprBV;
-
- void resetValues(AnalysisDataTy& AD) {
- DeclBV.resize(AD.NumDecls);
- DeclBV.reset();
- ExprBV.resize(AD.NumBlockExprs);
- ExprBV.reset();
- }
-
- bool operator==(const ValTy& RHS) const {
- return DeclBV == RHS.DeclBV && ExprBV == RHS.ExprBV;
- }
-
- void copyValues(const 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 ExprBV[AD.EMap[E]];
- }
-
- bool sizesEqual(ValTy& RHS) {
- return DeclBV.size() == RHS.DeclBV.size() &&
- ExprBV.size() == RHS.ExprBV.size();
- }
- };
+ typedef ExprDeclBitVector_Types::ValTy ValTy;
//===--------------------------------------------------------------------===//
// ObserverTy - Observer for querying DeclRefExprs that use an uninitalized
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=42408&r1=42407&r2=42408&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Thu Sep 27 13:20:22 2007
@@ -785,7 +785,7 @@
DIAG(warn_dead_store, WARNING, "value stored to variable is never used")
// CHECK: use of uninitialized values
-DIAG(warn_uninit_val, WARNING, "use of potentially uninitialized variable")
+DIAG(warn_uninit_val, WARNING, "use of uninitialized variable")
// CFString checking
DIAG(err_cfstring_literal_not_string_constant, ERROR,
More information about the cfe-commits
mailing list