Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//=- UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-=//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines APIs for invoking and reported uninitialized values
10
// warnings.
11
//
12
//===----------------------------------------------------------------------===//
13
 
14
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
15
#define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
16
 
17
#include "clang/Basic/LLVM.h"
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 Stmt;
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 = false;
43
 
44
  /// Is this use uninitialized whenever the variable declaration is reached?
45
  bool UninitAfterDecl = false;
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), AlwaysUninit(AlwaysUninit) {}
57
 
58
  void addUninitBranch(Branch B) {
59
    UninitBranches.push_back(B);
60
  }
61
 
62
  void setUninitAfterCall() { UninitAfterCall = true; }
63
  void setUninitAfterDecl() { UninitAfterDecl = true; }
64
 
65
  /// Get the expression containing the uninitialized use.
66
  const Expr *getUser() const { return User; }
67
 
68
  /// The kind of uninitialized use.
69
  enum Kind {
70
    /// The use might be uninitialized.
71
    Maybe,
72
 
73
    /// The use is uninitialized whenever a certain branch is taken.
74
    Sometimes,
75
 
76
    /// The use is uninitialized the first time it is reached after we reach
77
    /// the variable's declaration.
78
    AfterDecl,
79
 
80
    /// The use is uninitialized the first time it is reached after the function
81
    /// is called.
82
    AfterCall,
83
 
84
    /// The use is always uninitialized.
85
    Always
86
  };
87
 
88
  /// Get the kind of uninitialized use.
89
  Kind getKind() const {
90
    return AlwaysUninit ? Always :
91
           UninitAfterCall ? AfterCall :
92
           UninitAfterDecl ? AfterDecl :
93
           !branch_empty() ? Sometimes : Maybe;
94
  }
95
 
96
  using branch_iterator = SmallVectorImpl<Branch>::const_iterator;
97
 
98
  /// Branches which inevitably result in the variable being used uninitialized.
99
  branch_iterator branch_begin() const { return UninitBranches.begin(); }
100
  branch_iterator branch_end() const { return UninitBranches.end(); }
101
  bool branch_empty() const { return UninitBranches.empty(); }
102
};
103
 
104
class UninitVariablesHandler {
105
public:
106
  UninitVariablesHandler() = default;
107
  virtual ~UninitVariablesHandler();
108
 
109
  /// Called when the uninitialized variable is used at the given expression.
110
  virtual void handleUseOfUninitVariable(const VarDecl *vd,
111
                                         const UninitUse &use) {}
112
 
113
  /// Called when the uninitialized variable is used as const refernce argument.
114
  virtual void handleConstRefUseOfUninitVariable(const VarDecl *vd,
115
                                                 const UninitUse &use) {}
116
 
117
  /// Called when the uninitialized variable analysis detects the
118
  /// idiom 'int x = x'.  All other uses of 'x' within the initializer
119
  /// are handled by handleUseOfUninitVariable.
120
  virtual void handleSelfInit(const VarDecl *vd) {}
121
};
122
 
123
struct UninitVariablesAnalysisStats {
124
  unsigned NumVariablesAnalyzed;
125
  unsigned NumBlockVisits;
126
};
127
 
128
void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
129
                                       AnalysisDeclContext &ac,
130
                                       UninitVariablesHandler &handler,
131
                                       UninitVariablesAnalysisStats &stats);
132
 
133
} // namespace clang
134
 
135
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H