#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) { … }
namespace {
class DeclToIndex { … };
}
void DeclToIndex::computeMap(const DeclContext &dc) { … }
std::optional<unsigned> DeclToIndex::getValueIndex(const VarDecl *d) const { … }
enum Value { … };
static bool isUninitialized(const Value v) { … }
static bool isAlwaysUninit(const Value v) { … }
namespace {
ValueVector;
class CFGBlockValues { … };
}
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) { … }
namespace {
class FindVarResult { … };
}
static const Expr *stripCasts(ASTContext &C, const Expr *Ex) { … }
static FindVarResult findVar(const Expr *E, const DeclContext *DC) { … }
namespace {
class ClassifyRefs : public StmtVisitor<ClassifyRefs> { … };
}
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) { … }
namespace {
class TransferFunctions : public StmtVisitor<TransferFunctions> { … };
}
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) { … }
static bool runOnBlock(const CFGBlock *block, const CFG &cfg,
AnalysisDeclContext &ac, CFGBlockValues &vals,
const ClassifyRefs &classification,
llvm::BitVector &wasAnalyzed,
UninitVariablesHandler &handler) { … }
namespace {
struct PruneBlocksHandler : public UninitVariablesHandler { … };
}
void clang::runUninitializedVariablesAnalysis(
const DeclContext &dc,
const CFG &cfg,
AnalysisDeclContext &ac,
UninitVariablesHandler &handler,
UninitVariablesAnalysisStats &stats) { … }
UninitVariablesHandler::~UninitVariablesHandler() = default;