llvm/clang/lib/Analysis/UninitializedValues.cpp

//===- UninitializedValues.cpp - Find Uninitialized Values ----------------===//
//
// 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 implements uninitialized values analysis for source-level CFGs.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/Analyses/UninitializedValues.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
#include "clang/Analysis/FlowSensitive/DataflowWorklist.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PackedVector.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include <algorithm>
#include <cassert>
#include <optional>

usingnamespaceclang;

#define DEBUG_LOGGING

static bool recordIsNotEmpty(const RecordDecl *RD) {}

static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) {}

//------------------------------------------------------------------------====//
// DeclToIndex: a mapping from Decls we track to value indices.
//====------------------------------------------------------------------------//

namespace {

class DeclToIndex {};

} // namespace

void DeclToIndex::computeMap(const DeclContext &dc) {}

std::optional<unsigned> DeclToIndex::getValueIndex(const VarDecl *d) const {}

//------------------------------------------------------------------------====//
// CFGBlockValues: dataflow values for CFG blocks.
//====------------------------------------------------------------------------//

// These values are defined in such a way that a merge can be done using
// a bitwise OR.
enum Value {};

static bool isUninitialized(const Value v) {}

static bool isAlwaysUninit(const Value v) {}

namespace {

ValueVector;

class CFGBlockValues {};

} // namespace

CFGBlockValues::CFGBlockValues(const CFG &c) :{}

void CFGBlockValues::computeSetOfDeclarations(const DeclContext &dc) {}

#if DEBUG_LOGGING
static void printVector(const CFGBlock *block, ValueVector &bv,
                        unsigned num) {
  llvm::errs() << block->getBlockID() << " :";
  for (const auto &i : bv)
    llvm::errs() << ' ' << i;
  llvm::errs() << " : " << num << '\n';
}
#endif

void CFGBlockValues::setAllScratchValues(Value V) {}

void CFGBlockValues::mergeIntoScratch(ValueVector const &source,
                                      bool isFirst) {}

bool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) {}

void CFGBlockValues::resetScratch() {}

ValueVector::reference CFGBlockValues::operator[](const VarDecl *vd) {}

//------------------------------------------------------------------------====//
// Classification of DeclRefExprs as use or initialization.
//====------------------------------------------------------------------------//

namespace {

class FindVarResult {};

} // namespace

static const Expr *stripCasts(ASTContext &C, const Expr *Ex) {}

/// If E is an expression comprising a reference to a single variable, find that
/// variable.
static FindVarResult findVar(const Expr *E, const DeclContext *DC) {}

namespace {

/// Classify each DeclRefExpr as an initialization or a use. Any
/// DeclRefExpr which isn't explicitly classified will be assumed to have
/// escaped the analysis and will be treated as an initialization.
class ClassifyRefs : public StmtVisitor<ClassifyRefs> {};

} // namespace

static const DeclRefExpr *getSelfInitExpr(VarDecl *VD) {}

void ClassifyRefs::classify(const Expr *E, Class C) {}

void ClassifyRefs::VisitDeclStmt(DeclStmt *DS) {}

void ClassifyRefs::VisitBinaryOperator(BinaryOperator *BO) {}

void ClassifyRefs::VisitUnaryOperator(UnaryOperator *UO) {}

void ClassifyRefs::VisitOMPExecutableDirective(OMPExecutableDirective *ED) {}

static bool isPointerToConst(const QualType &QT) {}

static bool hasTrivialBody(CallExpr *CE) {}

void ClassifyRefs::VisitCallExpr(CallExpr *CE) {}

void ClassifyRefs::VisitCastExpr(CastExpr *CE) {}

//------------------------------------------------------------------------====//
// Transfer function for uninitialized values analysis.
//====------------------------------------------------------------------------//

namespace {

class TransferFunctions : public StmtVisitor<TransferFunctions> {};

} // namespace

void TransferFunctions::reportUse(const Expr *ex, const VarDecl *vd) {}

void TransferFunctions::reportConstRefUse(const Expr *ex, const VarDecl *vd) {}

void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *FS) {}

void TransferFunctions::VisitOMPExecutableDirective(
    OMPExecutableDirective *ED) {}

void TransferFunctions::VisitBlockExpr(BlockExpr *be) {}

void TransferFunctions::VisitCallExpr(CallExpr *ce) {}

void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *dr) {}

void TransferFunctions::VisitBinaryOperator(BinaryOperator *BO) {}

void TransferFunctions::VisitDeclStmt(DeclStmt *DS) {}

void TransferFunctions::VisitGCCAsmStmt(GCCAsmStmt *as) {}

void TransferFunctions::VisitObjCMessageExpr(ObjCMessageExpr *ME) {}

//------------------------------------------------------------------------====//
// High-level "driver" logic for uninitialized values analysis.
//====------------------------------------------------------------------------//

static bool runOnBlock(const CFGBlock *block, const CFG &cfg,
                       AnalysisDeclContext &ac, CFGBlockValues &vals,
                       const ClassifyRefs &classification,
                       llvm::BitVector &wasAnalyzed,
                       UninitVariablesHandler &handler) {}

namespace {

/// PruneBlocksHandler is a special UninitVariablesHandler that is used
/// to detect when a CFGBlock has any *potential* use of an uninitialized
/// variable.  It is mainly used to prune out work during the final
/// reporting pass.
struct PruneBlocksHandler : public UninitVariablesHandler {};

} // namespace

void clang::runUninitializedVariablesAnalysis(
    const DeclContext &dc,
    const CFG &cfg,
    AnalysisDeclContext &ac,
    UninitVariablesHandler &handler,
    UninitVariablesAnalysisStats &stats) {}

UninitVariablesHandler::~UninitVariablesHandler() = default;