Viewing file: UninitializedValues.h (4.15 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
//=- 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
|