1 //=- UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-=//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines APIs for invoking and reported uninitialized values
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
15 #define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
17 #include "clang/Basic/LLVM.h"
18 #include "llvm/ADT/SmallVector.h"
22 class AnalysisDeclContext;
29 /// A use of a variable, which might be uninitialized.
33 const Stmt *Terminator;
38 /// The expression which uses this variable.
41 /// Is this use uninitialized whenever the function is called?
42 bool UninitAfterCall = false;
44 /// Is this use uninitialized whenever the variable declaration is reached?
45 bool UninitAfterDecl = false;
47 /// Does this use always see an uninitialized value?
50 /// This use is always uninitialized if it occurs after any of these branches
52 SmallVector<Branch, 2> UninitBranches;
55 UninitUse(const Expr *User, bool AlwaysUninit)
56 : User(User), AlwaysUninit(AlwaysUninit) {}
58 void addUninitBranch(Branch B) {
59 UninitBranches.push_back(B);
62 void setUninitAfterCall() { UninitAfterCall = true; }
63 void setUninitAfterDecl() { UninitAfterDecl = true; }
65 /// Get the expression containing the uninitialized use.
66 const Expr *getUser() const { return User; }
68 /// The kind of uninitialized use.
70 /// The use might be uninitialized.
73 /// The use is uninitialized whenever a certain branch is taken.
76 /// The use is uninitialized the first time it is reached after we reach
77 /// the variable's declaration.
80 /// The use is uninitialized the first time it is reached after the function
84 /// The use is always uninitialized.
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;
96 using branch_iterator = SmallVectorImpl<Branch>::const_iterator;
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(); }
104 class UninitVariablesHandler {
106 UninitVariablesHandler() = default;
107 virtual ~UninitVariablesHandler();
109 /// Called when the uninitialized variable is used at the given expression.
110 virtual void handleUseOfUninitVariable(const VarDecl *vd,
111 const UninitUse &use) {}
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) {}
119 struct UninitVariablesAnalysisStats {
120 unsigned NumVariablesAnalyzed;
121 unsigned NumBlockVisits;
124 void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
125 AnalysisDeclContext &ac,
126 UninitVariablesHandler &handler,
127 UninitVariablesAnalysisStats &stats);
131 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H