]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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_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   /// 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:
55   UninitUse(const Expr *User, bool AlwaysUninit)
56       : User(User), UninitAfterCall(false), UninitAfterDecl(false),
57         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     /// 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.
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.
95   branch_iterator branch_begin() const { return UninitBranches.begin(); }
96   branch_iterator branch_end() const { return UninitBranches.end(); }
97   bool branch_empty() const { return UninitBranches.empty(); }
98 };
99
100 class UninitVariablesHandler {
101 public:
102   UninitVariablesHandler() {}
103   virtual ~UninitVariablesHandler();
104
105   /// Called when the uninitialized variable is used at the given expression.
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.
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