Home | History | Annotate | Download | only in Analyses
      1 //= UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines APIs for invoking and reported uninitialized values
     11 // warnings.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_UNINIT_VALS_H
     16 #define LLVM_CLANG_UNINIT_VALS_H
     17 
     18 #include "clang/AST/Stmt.h"
     19 #include "llvm/ADT/SmallVector.h"
     20 
     21 namespace clang {
     22 
     23 class AnalysisDeclContext;
     24 class CFG;
     25 class DeclContext;
     26 class Expr;
     27 class VarDecl;
     28 
     29 /// A use of a variable, which might be uninitialized.
     30 class UninitUse {
     31 public:
     32   struct Branch {
     33     const Stmt *Terminator;
     34     unsigned Output;
     35   };
     36 
     37 private:
     38   /// The expression which uses this variable.
     39   const Expr *User;
     40 
     41   /// Does this use always see an uninitialized value?
     42   bool AlwaysUninit;
     43 
     44   /// This use is always uninitialized if it occurs after any of these branches
     45   /// is taken.
     46   SmallVector<Branch, 2> UninitBranches;
     47 
     48 public:
     49   UninitUse(const Expr *User, bool AlwaysUninit) :
     50     User(User), AlwaysUninit(AlwaysUninit) {}
     51 
     52   void addUninitBranch(Branch B) {
     53     UninitBranches.push_back(B);
     54   }
     55 
     56   /// Get the expression containing the uninitialized use.
     57   const Expr *getUser() const { return User; }
     58 
     59   /// The kind of uninitialized use.
     60   enum Kind {
     61     /// The use might be uninitialized.
     62     Maybe,
     63     /// The use is uninitialized whenever a certain branch is taken.
     64     Sometimes,
     65     /// The use is always uninitialized.
     66     Always
     67   };
     68 
     69   /// Get the kind of uninitialized use.
     70   Kind getKind() const {
     71     return AlwaysUninit ? Always :
     72            !branch_empty() ? Sometimes : Maybe;
     73   }
     74 
     75   typedef SmallVectorImpl<Branch>::const_iterator branch_iterator;
     76   /// Branches which inevitably result in the variable being used uninitialized.
     77   branch_iterator branch_begin() const { return UninitBranches.begin(); }
     78   branch_iterator branch_end() const { return UninitBranches.end(); }
     79   bool branch_empty() const { return UninitBranches.empty(); }
     80 };
     81 
     82 class UninitVariablesHandler {
     83 public:
     84   UninitVariablesHandler() {}
     85   virtual ~UninitVariablesHandler();
     86 
     87   /// Called when the uninitialized variable is used at the given expression.
     88   virtual void handleUseOfUninitVariable(const VarDecl *vd,
     89                                          const UninitUse &use) {}
     90 
     91   /// Called when the uninitialized variable analysis detects the
     92   /// idiom 'int x = x'.  All other uses of 'x' within the initializer
     93   /// are handled by handleUseOfUninitVariable.
     94   virtual void handleSelfInit(const VarDecl *vd) {}
     95 };
     96 
     97 struct UninitVariablesAnalysisStats {
     98   unsigned NumVariablesAnalyzed;
     99   unsigned NumBlockVisits;
    100 };
    101 
    102 void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
    103                                        AnalysisDeclContext &ac,
    104                                        UninitVariablesHandler &handler,
    105                                        UninitVariablesAnalysisStats &stats);
    106 
    107 }
    108 #endif
    109