diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Analysis/MemoryLocation.cpp | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) |
Diffstat (limited to 'llvm/lib/Analysis/MemoryLocation.cpp')
-rw-r--r-- | llvm/lib/Analysis/MemoryLocation.cpp | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp index 2ed32227bd9e..e839f9e0dfb2 100644 --- a/llvm/lib/Analysis/MemoryLocation.cpp +++ b/llvm/lib/Analysis/MemoryLocation.cpp @@ -14,6 +14,7 @@ #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include <optional> using namespace llvm; void LocationSize::print(raw_ostream &OS) const { @@ -73,7 +74,8 @@ MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { RMWI->getAAMetadata()); } -Optional<MemoryLocation> MemoryLocation::getOrNone(const Instruction *Inst) { +std::optional<MemoryLocation> +MemoryLocation::getOrNone(const Instruction *Inst) { switch (Inst->getOpcode()) { case Instruction::Load: return get(cast<LoadInst>(Inst)); @@ -86,7 +88,7 @@ Optional<MemoryLocation> MemoryLocation::getOrNone(const Instruction *Inst) { case Instruction::AtomicRMW: return get(cast<AtomicRMWInst>(Inst)); default: - return None; + return std::nullopt; } } @@ -116,39 +118,39 @@ MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { return getForArgument(MI, 0, nullptr); } -Optional<MemoryLocation> +std::optional<MemoryLocation> MemoryLocation::getForDest(const CallBase *CB, const TargetLibraryInfo &TLI) { if (!CB->onlyAccessesArgMemory()) - return None; + return std::nullopt; if (CB->hasOperandBundles()) // TODO: remove implementation restriction - return None; + return std::nullopt; Value *UsedV = nullptr; - Optional<unsigned> UsedIdx; + std::optional<unsigned> UsedIdx; for (unsigned i = 0; i < CB->arg_size(); i++) { if (!CB->getArgOperand(i)->getType()->isPointerTy()) continue; - if (CB->onlyReadsMemory(i)) - continue; + if (CB->onlyReadsMemory(i)) + continue; if (!UsedV) { // First potentially writing parameter UsedV = CB->getArgOperand(i); UsedIdx = i; continue; } - UsedIdx = None; + UsedIdx = std::nullopt; if (UsedV != CB->getArgOperand(i)) // Can't describe writing to two distinct locations. // TODO: This results in an inprecision when two values derived from the // same object are passed as arguments to the same function. - return None; + return std::nullopt; } if (!UsedV) // We don't currently have a way to represent a "does not write" result // and thus have to be conservative and return unknown. - return None; + return std::nullopt; if (UsedIdx) return getForArgument(CB, *UsedIdx, &TLI); @@ -253,12 +255,17 @@ MemoryLocation MemoryLocation::getForArgument(const CallBase *Call, assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for str function"); return MemoryLocation::getAfter(Arg, AATags); - case LibFunc_memset_chk: { + case LibFunc_memset_chk: assert(ArgIdx == 0 && "Invalid argument index for memset_chk"); + LLVM_FALLTHROUGH; + case LibFunc_memcpy_chk: { + assert((ArgIdx == 0 || ArgIdx == 1) && + "Invalid argument index for memcpy_chk"); LocationSize Size = LocationSize::afterPointer(); if (const auto *Len = dyn_cast<ConstantInt>(Call->getArgOperand(2))) { - // memset_chk writes at most Len bytes. It may write less, if Len - // exceeds the specified max size and aborts. + // memset_chk writes at most Len bytes, memcpy_chk reads/writes at most + // Len bytes. They may read/write less, if Len exceeds the specified max + // size and aborts. Size = LocationSize::upperBound(Len->getZExtValue()); } return MemoryLocation(Arg, Size, AATags); |