1 //=- UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines APIs for invoking and reported uninitialized values
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
16 #define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
18 #include "clang/Basic/LLVM.h"
19 #include "llvm/ADT/SmallVector.h"
23 class AnalysisDeclContext;
30 /// A use of a variable, which might be uninitialized.
34 const Stmt *Terminator;
39 /// The expression which uses this variable.
42 /// Is this use uninitialized whenever the function is called?
43 bool UninitAfterCall = false;
45 /// Is this use uninitialized whenever the variable declaration is reached?
46 bool UninitAfterDecl = false;
48 /// Does this use always see an uninitialized value?
51 /// This use is always uninitialized if it occurs after any of these branches
53 SmallVector<Branch, 2> UninitBranches;
56 UninitUse(const Expr *User, bool AlwaysUninit)
57 : User(User), AlwaysUninit(AlwaysUninit) {}
59 void addUninitBranch(Branch B) {
60 UninitBranches.push_back(B);
63 void setUninitAfterCall() { UninitAfterCall = true; }
64 void setUninitAfterDecl() { UninitAfterDecl = true; }
66 /// Get the expression containing the uninitialized use.
67 const Expr *getUser() const { return User; }
69 /// The kind of uninitialized use.
71 /// The use might be uninitialized.
74 /// The use is uninitialized whenever a certain branch is taken.
77 /// The use is uninitialized the first time it is reached after we reach
78 /// the variable's declaration.
81 /// The use is uninitialized the first time it is reached after the function
85 /// The use is always uninitialized.
89 /// Get the kind of uninitialized use.
90 Kind getKind() const {
91 return AlwaysUninit ? Always :
92 UninitAfterCall ? AfterCall :
93 UninitAfterDecl ? AfterDecl :
94 !branch_empty() ? Sometimes : Maybe;
97 using branch_iterator = SmallVectorImpl<Branch>::const_iterator;
99 /// Branches which inevitably result in the variable being used uninitialized.
100 branch_iterator branch_begin() const { return UninitBranches.begin(); }
101 branch_iterator branch_end() const { return UninitBranches.end(); }
102 bool branch_empty() const { return UninitBranches.empty(); }
105 class UninitVariablesHandler {
107 UninitVariablesHandler() = default;
108 virtual ~UninitVariablesHandler();
110 /// Called when the uninitialized variable is used at the given expression.
111 virtual void handleUseOfUninitVariable(const VarDecl *vd,
112 const UninitUse &use) {}
114 /// Called when the uninitialized variable analysis detects the
115 /// idiom 'int x = x'. All other uses of 'x' within the initializer
116 /// are handled by handleUseOfUninitVariable.
117 virtual void handleSelfInit(const VarDecl *vd) {}
120 struct UninitVariablesAnalysisStats {
121 unsigned NumVariablesAnalyzed;
122 unsigned NumBlockVisits;
125 void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
126 AnalysisDeclContext &ac,
127 UninitVariablesHandler &handler,
128 UninitVariablesAnalysisStats &stats);
132 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H