]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h
MFC r244628:
[FreeBSD/stable/9.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 "llvm/ADT/SmallVector.h"
19
20 namespace clang {
21
22 class AnalysisDeclContext;
23 class CFG;
24 class DeclContext;
25 class Expr;
26 class VarDecl;
27
28 /// A use of a variable, which might be uninitialized.
29 class UninitUse {
30 public:
31   struct Branch {
32     const Stmt *Terminator;
33     unsigned Output;
34   };
35
36 private:
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
47 public:
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
81 class UninitVariablesHandler {
82 public:
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
96 struct UninitVariablesAnalysisStats {
97   unsigned NumVariablesAnalyzed;
98   unsigned NumBlockVisits;
99 };
100
101 void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
102                                        AnalysisDeclContext &ac,
103                                        UninitVariablesHandler &handler,
104                                        UninitVariablesAnalysisStats &stats);
105
106 }
107 #endif