Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  136.