aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/MemoryLocation.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Analysis/MemoryLocation.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'llvm/lib/Analysis/MemoryLocation.cpp')
-rw-r--r--llvm/lib/Analysis/MemoryLocation.cpp35
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);