]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/include/clang/Analysis/Analyses/UninitializedValues.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / include / clang / Analysis / Analyses / UninitializedValues.h
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 analysis detects the
114   /// idiom 'int x = x'.  All other uses of 'x' within the initializer
115   /// are handled by handleUseOfUninitVariable.
116   virtual void handleSelfInit(const VarDecl *vd) {}
117 };
118
119 struct UninitVariablesAnalysisStats {
120   unsigned NumVariablesAnalyzed;
121   unsigned NumBlockVisits;
122 };
123
124 void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
125                                        AnalysisDeclContext &ac,
126                                        UninitVariablesHandler &handler,
127                                        UninitVariablesAnalysisStats &stats);
128
129 } // namespace clang
130
131 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H