123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //=- UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-=//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines APIs for invoking and reported uninitialized values
- // warnings.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
- #define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
- #include "clang/Basic/LLVM.h"
- #include "llvm/ADT/SmallVector.h"
- namespace clang {
- class AnalysisDeclContext;
- class CFG;
- class DeclContext;
- class Expr;
- class Stmt;
- class VarDecl;
- /// A use of a variable, which might be uninitialized.
- class UninitUse {
- public:
- struct Branch {
- const Stmt *Terminator;
- unsigned Output;
- };
- private:
- /// The expression which uses this variable.
- const Expr *User;
- /// Is this use uninitialized whenever the function is called?
- bool UninitAfterCall = false;
- /// Is this use uninitialized whenever the variable declaration is reached?
- bool UninitAfterDecl = false;
- /// Does this use always see an uninitialized value?
- bool AlwaysUninit;
- /// This use is always uninitialized if it occurs after any of these branches
- /// is taken.
- SmallVector<Branch, 2> UninitBranches;
- public:
- UninitUse(const Expr *User, bool AlwaysUninit)
- : User(User), AlwaysUninit(AlwaysUninit) {}
- void addUninitBranch(Branch B) {
- UninitBranches.push_back(B);
- }
- void setUninitAfterCall() { UninitAfterCall = true; }
- void setUninitAfterDecl() { UninitAfterDecl = true; }
- /// Get the expression containing the uninitialized use.
- const Expr *getUser() const { return User; }
- /// The kind of uninitialized use.
- enum Kind {
- /// The use might be uninitialized.
- Maybe,
- /// The use is uninitialized whenever a certain branch is taken.
- Sometimes,
- /// The use is uninitialized the first time it is reached after we reach
- /// the variable's declaration.
- AfterDecl,
- /// The use is uninitialized the first time it is reached after the function
- /// is called.
- AfterCall,
- /// The use is always uninitialized.
- Always
- };
- /// Get the kind of uninitialized use.
- Kind getKind() const {
- return AlwaysUninit ? Always :
- UninitAfterCall ? AfterCall :
- UninitAfterDecl ? AfterDecl :
- !branch_empty() ? Sometimes : Maybe;
- }
- using branch_iterator = SmallVectorImpl<Branch>::const_iterator;
- /// Branches which inevitably result in the variable being used uninitialized.
- branch_iterator branch_begin() const { return UninitBranches.begin(); }
- branch_iterator branch_end() const { return UninitBranches.end(); }
- bool branch_empty() const { return UninitBranches.empty(); }
- };
- class UninitVariablesHandler {
- public:
- UninitVariablesHandler() = default;
- virtual ~UninitVariablesHandler();
- /// Called when the uninitialized variable is used at the given expression.
- virtual void handleUseOfUninitVariable(const VarDecl *vd,
- const UninitUse &use) {}
- /// Called when the uninitialized variable is used as const refernce argument.
- virtual void handleConstRefUseOfUninitVariable(const VarDecl *vd,
- const UninitUse &use) {}
- /// Called when the uninitialized variable analysis detects the
- /// idiom 'int x = x'. All other uses of 'x' within the initializer
- /// are handled by handleUseOfUninitVariable.
- virtual void handleSelfInit(const VarDecl *vd) {}
- };
- struct UninitVariablesAnalysisStats {
- unsigned NumVariablesAnalyzed;
- unsigned NumBlockVisits;
- };
- void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
- AnalysisDeclContext &ac,
- UninitVariablesHandler &handler,
- UninitVariablesAnalysisStats &stats);
- } // namespace clang
- #endif // LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|