UninitializedValues.h revision 8a1fdfc69cc6c2ccbfd57fc8ff643c589da9df9b
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
21namespace clang {
22
23class AnalysisDeclContext;
24class CFG;
25class DeclContext;
26class Expr;
27class VarDecl;
28
29/// A use of a variable, which might be uninitialized.
30class UninitUse {
31public:
32  struct Branch {
33    const Stmt *Terminator;
34    unsigned Output;
35  };
36
37private:
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
54public:
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
100class UninitVariablesHandler {
101public:
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
115struct UninitVariablesAnalysisStats {
116  unsigned NumVariablesAnalyzed;
117  unsigned NumBlockVisits;
118};
119
120void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
121                                       AnalysisDeclContext &ac,
122                                       UninitVariablesHandler &handler,
123                                       UninitVariablesAnalysisStats &stats);
124
125}
126#endif
127