diff options
author | Nuno Lopes <nunoplopes@sapo.pt> | 2012-06-28 16:34:03 +0000 |
---|---|---|
committer | Nuno Lopes <nunoplopes@sapo.pt> | 2012-06-28 16:34:03 +0000 |
commit | 41a3f251346681e21171879dce409b2e6a3ba750 (patch) | |
tree | 0cb88b83a912fb5cbe5f2de1e519f1b5bedb58dd /lib/Analysis/MemoryBuiltins.cpp | |
parent | e50487796d49624bf174bd08a86d20fcdbfb45c1 (diff) |
MemoryBuiltins:
- recognize C++ new(std::nothrow) friends
- ignore ExtractElement and ExtractValue instructions in size/offset analysis (all easy cases are probably folded away before we get here)
- also recognize realloc as noalias
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159356 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/MemoryBuiltins.cpp')
-rw-r--r-- | lib/Analysis/MemoryBuiltins.cpp | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp index 6b21b73f22..b60b728b91 100644 --- a/lib/Analysis/MemoryBuiltins.cpp +++ b/lib/Analysis/MemoryBuiltins.cpp @@ -46,19 +46,25 @@ struct AllocFnsTy { signed char FstParam, SndParam; }; +// FIXME: certain users need more information. E.g., SimplifyLibCalls needs to +// know which functions are nounwind, noalias, nocapture parameters, etc. static const AllocFnsTy AllocationFnData[] = { - {"malloc", MallocLike, 1, 0, -1}, - {"valloc", MallocLike, 1, 0, -1}, - {"_Znwj", MallocLike, 1, 0, -1}, // operator new(unsigned int) - {"_Znwm", MallocLike, 1, 0, -1}, // operator new(unsigned long) - {"_Znaj", MallocLike, 1, 0, -1}, // operator new[](unsigned int) - {"_Znam", MallocLike, 1, 0, -1}, // operator new[](unsigned long) - {"posix_memalign", MallocLike, 3, 2, -1}, - {"calloc", CallocLike, 2, 0, 1}, - {"realloc", ReallocLike, 2, 1, -1}, - {"reallocf", ReallocLike, 2, 1, -1}, - {"strdup", StrDupLike, 1, -1, -1}, - {"strndup", StrDupLike, 2, -1, -1} + {"malloc", MallocLike, 1, 0, -1}, + {"valloc", MallocLike, 1, 0, -1}, + {"_Znwj", MallocLike, 1, 0, -1}, // new(unsigned int) + {"_ZnwjRKSt9nothrow_t", MallocLike, 2, 0, -1}, // new(unsigned int, nothrow) + {"_Znwm", MallocLike, 1, 0, -1}, // new(unsigned long) + {"_ZnwmRKSt9nothrow_t", MallocLike, 2, 0, -1}, // new(unsigned long, nothrow) + {"_Znaj", MallocLike, 1, 0, -1}, // new[](unsigned int) + {"_ZnajRKSt9nothrow_t", MallocLike, 2, 0, -1}, // new[](unsigned int, nothrow) + {"_Znam", MallocLike, 1, 0, -1}, // new[](unsigned long) + {"_ZnamRKSt9nothrow_t", MallocLike, 2, 0, -1}, // new[](unsigned long, nothrow) + {"posix_memalign", MallocLike, 3, 2, -1}, + {"calloc", CallocLike, 2, 0, 1}, + {"realloc", ReallocLike, 2, 1, -1}, + {"reallocf", ReallocLike, 2, 1, -1}, + {"strdup", StrDupLike, 1, -1, -1}, + {"strndup", StrDupLike, 2, -1, -1} }; @@ -131,9 +137,11 @@ bool llvm::isAllocationFn(const Value *V, bool LookThroughBitCast) { } /// \brief Tests if a value is a call or invoke to a function that returns a -/// NoAlias pointer (including malloc/calloc/strdup-like functions). +/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions). bool llvm::isNoAliasFn(const Value *V, bool LookThroughBitCast) { - return isAllocLikeFn(V, LookThroughBitCast) || + // it's safe to consider realloc as noalias since accessing the original + // pointer is undefined behavior + return isAllocationFn(V, LookThroughBitCast) || hasNoAliasAttr(V, LookThroughBitCast); } @@ -441,6 +449,11 @@ ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull&) { } SizeOffsetType +ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst&) { + return unknown(); +} + +SizeOffsetType ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst&) { // Easy cases were already folded by previous passes. return unknown(); @@ -617,6 +630,16 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) { } SizeOffsetEvalType +ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst&) { + return unknown(); +} + +SizeOffsetEvalType +ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst&) { + return unknown(); +} + +SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) { SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand()); if (!bothKnown(PtrData)) |