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