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
20namespace clang {
21
22class AnalysisDeclContext;
23class CFG;
24class DeclContext;
25class Expr;
26class VarDecl;
27
28/// A use of a variable, which might be uninitialized.
29class UninitUse {
30public:
31  struct Branch {
32    const Stmt *Terminator;
33    unsigned Output;
34  };
35
36private:
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
47public:
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
81class UninitVariablesHandler {
82public:
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
96struct UninitVariablesAnalysisStats {
97  unsigned NumVariablesAnalyzed;
98  unsigned NumBlockVisits;
99};
100
101void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
102                                       AnalysisDeclContext &ac,
103                                       UninitVariablesHandler &handler,
104                                       UninitVariablesAnalysisStats &stats);
105
106}
107#endif
108