[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