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_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H 16 #define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_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 /// Is this use uninitialized whenever the function is called? 42 bool UninitAfterCall; 43 44 /// Is this use uninitialized whenever the variable declaration is reached? 45 bool UninitAfterDecl; 46 47 /// Does this use always see an uninitialized value? 48 bool AlwaysUninit; 49 50 /// This use is always uninitialized if it occurs after any of these branches 51 /// is taken. 52 SmallVector<Branch, 2> UninitBranches; 53 54 public: UninitUse(const Expr * User,bool AlwaysUninit)55 UninitUse(const Expr *User, bool AlwaysUninit) 56 : User(User), UninitAfterCall(false), UninitAfterDecl(false), 57 AlwaysUninit(AlwaysUninit) {} 58 addUninitBranch(Branch B)59 void addUninitBranch(Branch B) { 60 UninitBranches.push_back(B); 61 } 62 setUninitAfterCall()63 void setUninitAfterCall() { UninitAfterCall = true; } setUninitAfterDecl()64 void setUninitAfterDecl() { UninitAfterDecl = true; } 65 66 /// Get the expression containing the uninitialized use. getUser()67 const Expr *getUser() const { return User; } 68 69 /// The kind of uninitialized use. 70 enum Kind { 71 /// The use might be uninitialized. 72 Maybe, 73 /// The use is uninitialized whenever a certain branch is taken. 74 Sometimes, 75 /// The use is uninitialized the first time it is reached after we reach 76 /// the variable's declaration. 77 AfterDecl, 78 /// The use is uninitialized the first time it is reached after the function 79 /// is called. 80 AfterCall, 81 /// The use is always uninitialized. 82 Always 83 }; 84 85 /// Get the kind of uninitialized use. getKind()86 Kind getKind() const { 87 return AlwaysUninit ? Always : 88 UninitAfterCall ? AfterCall : 89 UninitAfterDecl ? AfterDecl : 90 !branch_empty() ? Sometimes : Maybe; 91 } 92 93 typedef SmallVectorImpl<Branch>::const_iterator branch_iterator; 94 /// Branches which inevitably result in the variable being used uninitialized. branch_begin()95 branch_iterator branch_begin() const { return UninitBranches.begin(); } branch_end()96 branch_iterator branch_end() const { return UninitBranches.end(); } branch_empty()97 bool branch_empty() const { return UninitBranches.empty(); } 98 }; 99 100 class UninitVariablesHandler { 101 public: UninitVariablesHandler()102 UninitVariablesHandler() {} 103 virtual ~UninitVariablesHandler(); 104 105 /// Called when the uninitialized variable is used at the given expression. handleUseOfUninitVariable(const VarDecl * vd,const UninitUse & use)106 virtual void handleUseOfUninitVariable(const VarDecl *vd, 107 const UninitUse &use) {} 108 109 /// Called when the uninitialized variable analysis detects the 110 /// idiom 'int x = x'. All other uses of 'x' within the initializer 111 /// are handled by handleUseOfUninitVariable. handleSelfInit(const VarDecl * vd)112 virtual void handleSelfInit(const VarDecl *vd) {} 113 }; 114 115 struct UninitVariablesAnalysisStats { 116 unsigned NumVariablesAnalyzed; 117 unsigned NumBlockVisits; 118 }; 119 120 void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg, 121 AnalysisDeclContext &ac, 122 UninitVariablesHandler &handler, 123 UninitVariablesAnalysisStats &stats); 124 125 } 126 #endif 127