aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/MemoryBuiltins.cpp
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2016-12-23 01:18:09 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2016-12-23 01:18:09 +0000
commitccae43a247b0791f78ea89b9cb7e59fa70f5000d (patch)
tree5759948276c77ef8d18533abeee0bd0aab144de9 /llvm/lib/Analysis/MemoryBuiltins.cpp
parent2e97554245a4a5a055c2846cc8d93dffb48101f6 (diff)
downloadllvm-ccae43a247b0791f78ea89b9cb7e59fa70f5000d.zip
llvm-ccae43a247b0791f78ea89b9cb7e59fa70f5000d.tar.gz
llvm-ccae43a247b0791f78ea89b9cb7e59fa70f5000d.tar.bz2
Don't consider allocsize functions to be allocation functions.
This patch fixes some ASAN unittest failures on FreeBSD. See the cfe-commits email thread for r290169 for more on those. According to the LangRef, the allocsize attribute only tells us about the number of bytes that exist at the memory location pointed to by the return value of a function. It does not necessarily mean that the function will only ever allocate. So, we need to be very careful about treating functions with allocsize as general allocation functions. This patch makes us fully conservative in this regard, though I suspect that we have room to be a bit more aggressive if we want. This has a FIXME that can be fixed by a relatively straightforward refactor; I just wanted to keep this patch minimal. If this sticks, I'll come back and fix it in a few days. llvm-svn: 290397
Diffstat (limited to 'llvm/lib/Analysis/MemoryBuiltins.cpp')
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp51
1 files changed, 28 insertions, 23 deletions
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index eaac506..3e464f0 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -109,25 +109,6 @@ static Optional<AllocFnsTy> getAllocationData(const Value *V, AllocType AllocTy,
if (!Callee)
return None;
- // If it has allocsize, we can skip checking if it's a known function.
- //
- // MallocLike is chosen here because allocsize makes no guarantees about the
- // nullness of the result of the function, nor does it deal with strings, nor
- // does it require that the memory returned is zeroed out.
- const AllocType AllocSizeAllocTy = MallocLike;
- if ((AllocTy & AllocSizeAllocTy) == AllocSizeAllocTy &&
- Callee->hasFnAttribute(Attribute::AllocSize)) {
- Attribute Attr = Callee->getFnAttribute(Attribute::AllocSize);
- std::pair<unsigned, Optional<unsigned>> Args = Attr.getAllocSizeArgs();
-
- AllocFnsTy Result;
- Result.AllocTy = AllocSizeAllocTy;
- Result.NumParams = Callee->getNumOperands();
- Result.FstParam = Args.first;
- Result.SndParam = Args.second.getValueOr(-1);
- return Result;
- }
-
// Make sure that the function is available.
StringRef FnName = Callee->getName();
LibFunc::Func TLIFn;
@@ -163,6 +144,32 @@ static Optional<AllocFnsTy> getAllocationData(const Value *V, AllocType AllocTy,
return None;
}
+static Optional<AllocFnsTy> getAllocationSize(const Value *V,
+ const TargetLibraryInfo *TLI) {
+ // Prefer to use existing information over allocsize. This will give us an
+ // accurate AllocTy.
+ if (Optional<AllocFnsTy> Data =
+ getAllocationData(V, AnyAlloc, TLI, /*LookThroughBitCast=*/false))
+ return Data;
+
+ // FIXME: Not calling getCalledFunction twice would be nice.
+ const Function *Callee = getCalledFunction(V, /*LookThroughBitCast=*/false);
+ if (!Callee || !Callee->hasFnAttribute(Attribute::AllocSize))
+ return None;
+
+ Attribute Attr = Callee->getFnAttribute(Attribute::AllocSize);
+ std::pair<unsigned, Optional<unsigned>> Args = Attr.getAllocSizeArgs();
+
+ AllocFnsTy Result;
+ // Because allocsize only tells us how many bytes are allocated, we're not
+ // really allowed to assume anything, so we use MallocLike.
+ Result.AllocTy = MallocLike;
+ Result.NumParams = Callee->getNumOperands();
+ Result.FstParam = Args.first;
+ Result.SndParam = Args.second.getValueOr(-1);
+ return Result;
+}
+
static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
ImmutableCallSite CS(LookThroughBitCast ? V->stripPointerCasts() : V);
return CS && CS.paramHasAttr(AttributeSet::ReturnIndex, Attribute::NoAlias);
@@ -505,8 +512,7 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
}
SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
- Optional<AllocFnsTy> FnData =
- getAllocationData(CS.getInstruction(), AnyAlloc, TLI);
+ Optional<AllocFnsTy> FnData = getAllocationSize(CS.getInstruction(), TLI);
if (!FnData)
return unknown();
@@ -765,8 +771,7 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
}
SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) {
- Optional<AllocFnsTy> FnData =
- getAllocationData(CS.getInstruction(), AnyAlloc, TLI);
+ Optional<AllocFnsTy> FnData = getAllocationSize(CS.getInstruction(), TLI);
if (!FnData)
return unknown();