From ae852750b34a842c33e0cc94aafd331742f980f0 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 24 Nov 2022 19:17:48 +0000 Subject: [PATCH] [MemoryLocation] Support memcpy_chk in getForArgument. Similar to 9f9e8ba114ce, add support for memcyp_chk to MemoryLocation::getForArgument. The size argument for memcpy_chk is an upper bound for the size of the pointer argument. memcpy_chk may read/write less than the specified length, if it exceeds the specified max size and aborts. Reviewed By: xbolva00, jdoerfert Differential Revision: https://reviews.llvm.org/D138613 --- llvm/lib/Analysis/MemoryLocation.cpp | 11 ++++++++--- llvm/test/Analysis/BasicAA/libfuncs.ll | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp index 2ed3222..252eedb 100644 --- a/llvm/lib/Analysis/MemoryLocation.cpp +++ b/llvm/lib/Analysis/MemoryLocation.cpp @@ -253,12 +253,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(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); diff --git a/llvm/test/Analysis/BasicAA/libfuncs.ll b/llvm/test/Analysis/BasicAA/libfuncs.ll index 96ce581c..08faefc 100644 --- a/llvm/test/Analysis/BasicAA/libfuncs.ll +++ b/llvm/test/Analysis/BasicAA/libfuncs.ll @@ -323,9 +323,9 @@ define i8* @test_memcpy_chk_const_size(i8* noalias %a, i8* noalias %b, i64 %n) { ; CHECK: Just Mod: Ptr: i8* %a <-> %res = tail call i8* @__memcpy_chk(i8* %a, i8* %b, i64 4, i64 %n) ; CHECK-NEXT: Just Mod: Ptr: i8* %res <-> %res = tail call i8* @__memcpy_chk(i8* %a, i8* %b, i64 4, i64 %n) ; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.1 <-> %res = tail call i8* @__memcpy_chk(i8* %a, i8* %b, i64 4, i64 %n) -; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.5 <-> %res = tail call i8* @__memcpy_chk(i8* %a, i8* %b, i64 4, i64 %n) +; CHECK-NEXT: NoModRef: Ptr: i8* %a.gep.5 <-> %res = tail call i8* @__memcpy_chk(i8* %a, i8* %b, i64 4, i64 %n) ; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.1 <-> %res = tail call i8* @__memcpy_chk(i8* %a, i8* %b, i64 4, i64 %n) -; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.5 <-> %res = tail call i8* @__memcpy_chk(i8* %a, i8* %b, i64 4, i64 %n) +; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> %res = tail call i8* @__memcpy_chk(i8* %a, i8* %b, i64 4, i64 %n) ; entry: load i8, i8* %a -- 2.7.4