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 20namespace clang { 21 22class AnalysisDeclContext; 23class CFG; 24class DeclContext; 25class Expr; 26class Stmt; 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 = 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 54public: 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 104class UninitVariablesHandler { 105public: 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 123struct UninitVariablesAnalysisStats { 124 unsigned NumVariablesAnalyzed; 125 unsigned NumBlockVisits; 126}; 127 128void 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 136