#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/TargetFolder.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/Utils/Local.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <numeric>
#include <optional>
#include <type_traits>
#include <utility>
usingnamespacellvm;
#define DEBUG_TYPE …
static cl::opt<unsigned> ObjectSizeOffsetVisitorMaxVisitInstructions(
"object-size-offset-visitor-max-visit-instructions",
cl::desc("Maximum number of instructions for ObjectSizeOffsetVisitor to "
"look at"),
cl::init(100));
enum AllocType : uint8_t { … };
enum class MallocFamily { … };
StringRef mangledNameForMallocFamily(const MallocFamily &Family) { … }
struct AllocFnsTy { … };
static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = …;
static const Function *getCalledFunction(const Value *V) { … }
static std::optional<AllocFnsTy>
getAllocationDataForFunction(const Function *Callee, AllocType AllocTy,
const TargetLibraryInfo *TLI) { … }
static std::optional<AllocFnsTy>
getAllocationData(const Value *V, AllocType AllocTy,
const TargetLibraryInfo *TLI) { … }
static std::optional<AllocFnsTy>
getAllocationData(const Value *V, AllocType AllocTy,
function_ref<const TargetLibraryInfo &(Function &)> GetTLI) { … }
static std::optional<AllocFnsTy>
getAllocationSize(const CallBase *CB, const TargetLibraryInfo *TLI) { … }
static AllocFnKind getAllocFnKind(const Value *V) { … }
static AllocFnKind getAllocFnKind(const Function *F) { … }
static bool checkFnAllocKind(const Value *V, AllocFnKind Wanted) { … }
static bool checkFnAllocKind(const Function *F, AllocFnKind Wanted) { … }
bool llvm::isAllocationFn(const Value *V, const TargetLibraryInfo *TLI) { … }
bool llvm::isAllocationFn(
const Value *V,
function_ref<const TargetLibraryInfo &(Function &)> GetTLI) { … }
bool llvm::isNewLikeFn(const Value *V, const TargetLibraryInfo *TLI) { … }
bool llvm::isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) { … }
bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI) { … }
bool llvm::isReallocLikeFn(const Function *F) { … }
Value *llvm::getReallocatedOperand(const CallBase *CB) { … }
bool llvm::isRemovableAlloc(const CallBase *CB, const TargetLibraryInfo *TLI) { … }
Value *llvm::getAllocAlignment(const CallBase *V,
const TargetLibraryInfo *TLI) { … }
static bool CheckedZextOrTrunc(APInt &I, unsigned IntTyBits) { … }
std::optional<APInt>
llvm::getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI,
function_ref<const Value *(const Value *)> Mapper) { … }
Constant *llvm::getInitialValueOfAllocation(const Value *V,
const TargetLibraryInfo *TLI,
Type *Ty) { … }
struct FreeFnsTy { … };
static const std::pair<LibFunc, FreeFnsTy> FreeFnData[] = …;
std::optional<FreeFnsTy> getFreeFunctionDataForFunction(const Function *Callee,
const LibFunc TLIFn) { … }
std::optional<StringRef>
llvm::getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI) { … }
bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) { … }
Value *llvm::getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI) { … }
static APInt getSizeWithOverflow(const SizeOffsetAPInt &Data) { … }
bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
const TargetLibraryInfo *TLI, ObjectSizeOpts Opts) { … }
Value *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
const DataLayout &DL,
const TargetLibraryInfo *TLI,
bool MustSucceed) { … }
Value *llvm::lowerObjectSizeCall(
IntrinsicInst *ObjectSize, const DataLayout &DL,
const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
SmallVectorImpl<Instruction *> *InsertedInstructions) { … }
STATISTIC(ObjectVisitorArgument,
"Number of arguments with unsolved size and offset");
STATISTIC(ObjectVisitorLoad,
"Number of load instructions with unsolved size and offset");
APInt ObjectSizeOffsetVisitor::align(APInt Size, MaybeAlign Alignment) { … }
ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL,
const TargetLibraryInfo *TLI,
LLVMContext &Context,
ObjectSizeOpts Options)
: … { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::compute(Value *V) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::computeImpl(Value *V) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::computeValue(Value *V) { … }
bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(APInt &I) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitArgument(Argument &A) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitCallBase(CallBase &CB) { … }
SizeOffsetAPInt
ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull &CPN) { … }
SizeOffsetAPInt
ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst &) { … }
SizeOffsetAPInt
ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst &) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) { … }
SizeOffsetAPInt
ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitIntToPtrInst(IntToPtrInst &) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::findLoadSizeOffset(
LoadInst &Load, BasicBlock &BB, BasicBlock::iterator From,
SmallDenseMap<BasicBlock *, SizeOffsetAPInt, 8> &VisitedBlocks,
unsigned &ScannedInstCount) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitLoadInst(LoadInst &LI) { … }
SizeOffsetAPInt
ObjectSizeOffsetVisitor::combineSizeOffset(SizeOffsetAPInt LHS,
SizeOffsetAPInt RHS) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitPHINode(PHINode &PN) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitUndefValue(UndefValue &) { … }
SizeOffsetAPInt ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) { … }
SizeOffsetValue::SizeOffsetValue(const SizeOffsetWeakTrackingVH &SOT)
: … { … }
ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context,
ObjectSizeOpts EvalOpts)
: … { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::compute(Value *V) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::compute_(Value *V) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::visitCallBase(CallBase &CB) { … }
SizeOffsetValue
ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst &) { … }
SizeOffsetValue
ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst &) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::visitIntToPtrInst(IntToPtrInst &) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::visitLoadInst(LoadInst &LI) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) { … }
SizeOffsetValue ObjectSizeOffsetEvaluator::visitInstruction(Instruction &I) { … }