]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Analysis / Analyses / UninitializedValues.h
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/Basic/LLVM.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 Stmt;
28 class VarDecl;
29
30 /// A use of a variable, which might be uninitialized.
31 class UninitUse {
32 public:
33   struct Branch {
34     const Stmt *Terminator;
35     unsigned Output;
36   };
37
38 private:
39   /// The expression which uses this variable.
40   const Expr *User;
41
42   /// Is this use uninitialized whenever the function is called?
43   bool UninitAfterCall = false;
44
45   /// Is this use uninitialized whenever the variable declaration is reached?
46   bool UninitAfterDecl = false;
47
48   /// Does this use always see an uninitialized value?
49   bool AlwaysUninit;
50
51   /// This use is always uninitialized if it occurs after any of these branches
52   /// is taken.
53   SmallVector<Branch, 2> UninitBranches;
54
55 public:
56   UninitUse(const Expr *User, bool AlwaysUninit)
57       : User(User), AlwaysUninit(AlwaysUninit) {}
58
59   void addUninitBranch(Branch B) {
60     UninitBranches.push_back(B);
61   }
62
63   void setUninitAfterCall() { UninitAfterCall = true; }
64   void setUninitAfterDecl() { UninitAfterDecl = true; }
65
66   /// Get the expression containing the uninitialized use.
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
74     /// The use is uninitialized whenever a certain branch is taken.
75     Sometimes,
76
77     /// The use is uninitialized the first time it is reached after we reach
78     /// the variable's declaration.
79     AfterDecl,
80
81     /// The use is uninitialized the first time it is reached after the function
82     /// is called.
83     AfterCall,
84
85     /// The use is always uninitialized.
86     Always
87   };
88
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;
95   }
96
97   using branch_iterator = SmallVectorImpl<Branch>::const_iterator;
98
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(); }
103 };
104
105 class UninitVariablesHandler {
106 public:
107   UninitVariablesHandler() = default;
108   virtual ~UninitVariablesHandler();
109
110   /// Called when the uninitialized variable is used at the given expression.
111   virtual void handleUseOfUninitVariable(const VarDecl *vd,
112                                          const UninitUse &use) {}
113
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) {}
118 };
119
120 struct UninitVariablesAnalysisStats {
121   unsigned NumVariablesAnalyzed;
122   unsigned NumBlockVisits;
123 };
124
125 void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
126                                        AnalysisDeclContext &ac,
127                                        UninitVariablesHandler &handler,
128                                        UninitVariablesAnalysisStats &stats);
129
130 } // namespace clang
131
132 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H