Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:24

0001 //=- UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-=//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines APIs for invoking and reported uninitialized values
0010 // warnings.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
0015 #define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
0016 
0017 #include "clang/Basic/LLVM.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 
0020 namespace clang {
0021 
0022 class AnalysisDeclContext;
0023 class CFG;
0024 class DeclContext;
0025 class Expr;
0026 class Stmt;
0027 class VarDecl;
0028 
0029 /// A use of a variable, which might be uninitialized.
0030 class UninitUse {
0031 public:
0032   struct Branch {
0033     const Stmt *Terminator;
0034     unsigned Output;
0035   };
0036 
0037 private:
0038   /// The expression which uses this variable.
0039   const Expr *User;
0040 
0041   /// Is this use uninitialized whenever the function is called?
0042   bool UninitAfterCall = false;
0043 
0044   /// Is this use uninitialized whenever the variable declaration is reached?
0045   bool UninitAfterDecl = false;
0046 
0047   /// Does this use always see an uninitialized value?
0048   bool AlwaysUninit;
0049 
0050   /// This use is always uninitialized if it occurs after any of these branches
0051   /// is taken.
0052   SmallVector<Branch, 2> UninitBranches;
0053 
0054 public:
0055   UninitUse(const Expr *User, bool AlwaysUninit)
0056       : User(User), AlwaysUninit(AlwaysUninit) {}
0057 
0058   void addUninitBranch(Branch B) {
0059     UninitBranches.push_back(B);
0060   }
0061 
0062   void setUninitAfterCall() { UninitAfterCall = true; }
0063   void setUninitAfterDecl() { UninitAfterDecl = true; }
0064 
0065   /// Get the expression containing the uninitialized use.
0066   const Expr *getUser() const { return User; }
0067 
0068   /// The kind of uninitialized use.
0069   enum Kind {
0070     /// The use might be uninitialized.
0071     Maybe,
0072 
0073     /// The use is uninitialized whenever a certain branch is taken.
0074     Sometimes,
0075 
0076     /// The use is uninitialized the first time it is reached after we reach
0077     /// the variable's declaration.
0078     AfterDecl,
0079 
0080     /// The use is uninitialized the first time it is reached after the function
0081     /// is called.
0082     AfterCall,
0083 
0084     /// The use is always uninitialized.
0085     Always
0086   };
0087 
0088   /// Get the kind of uninitialized use.
0089   Kind getKind() const {
0090     return AlwaysUninit ? Always :
0091            UninitAfterCall ? AfterCall :
0092            UninitAfterDecl ? AfterDecl :
0093            !branch_empty() ? Sometimes : Maybe;
0094   }
0095 
0096   using branch_iterator = SmallVectorImpl<Branch>::const_iterator;
0097 
0098   /// Branches which inevitably result in the variable being used uninitialized.
0099   branch_iterator branch_begin() const { return UninitBranches.begin(); }
0100   branch_iterator branch_end() const { return UninitBranches.end(); }
0101   bool branch_empty() const { return UninitBranches.empty(); }
0102 };
0103 
0104 class UninitVariablesHandler {
0105 public:
0106   UninitVariablesHandler() = default;
0107   virtual ~UninitVariablesHandler();
0108 
0109   /// Called when the uninitialized variable is used at the given expression.
0110   virtual void handleUseOfUninitVariable(const VarDecl *vd,
0111                                          const UninitUse &use) {}
0112 
0113   /// Called when the uninitialized variable is used as const refernce argument.
0114   virtual void handleConstRefUseOfUninitVariable(const VarDecl *vd,
0115                                                  const UninitUse &use) {}
0116 
0117   /// Called when the uninitialized variable analysis detects the
0118   /// idiom 'int x = x'.  All other uses of 'x' within the initializer
0119   /// are handled by handleUseOfUninitVariable.
0120   virtual void handleSelfInit(const VarDecl *vd) {}
0121 };
0122 
0123 struct UninitVariablesAnalysisStats {
0124   unsigned NumVariablesAnalyzed;
0125   unsigned NumBlockVisits;
0126 };
0127 
0128 void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
0129                                        AnalysisDeclContext &ac,
0130                                        UninitVariablesHandler &handler,
0131                                        UninitVariablesAnalysisStats &stats);
0132 
0133 } // namespace clang
0134 
0135 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H