From 41a3f251346681e21171879dce409b2e6a3ba750 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Thu, 28 Jun 2012 16:34:03 +0000 Subject: [PATCH] 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 --- include/llvm/Analysis/MemoryBuiltins.h | 5 ++- lib/Analysis/MemoryBuiltins.cpp | 51 +++++++++++++++++++------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index 4072878f39b..f8184ff43ec 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -37,7 +37,7 @@ class Value; bool isAllocationFn(const Value *V, bool LookThroughBitCast = false); /// \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 isNoAliasFn(const Value *V, bool LookThroughBitCast = false); /// \brief Tests if a value is a call or invoke to a library function that @@ -174,6 +174,7 @@ public: SizeOffsetType visitArgument(Argument &A); SizeOffsetType visitCallSite(CallSite CS); SizeOffsetType visitConstantPointerNull(ConstantPointerNull&); + SizeOffsetType visitExtractElementInst(ExtractElementInst &I); SizeOffsetType visitExtractValueInst(ExtractValueInst &I); SizeOffsetType visitGEPOperator(GEPOperator &GEP); SizeOffsetType visitGlobalVariable(GlobalVariable &GV); @@ -233,6 +234,8 @@ public: SizeOffsetEvalType visitAllocaInst(AllocaInst &I); SizeOffsetEvalType visitCallSite(CallSite CS); + SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I); + SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I); SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP); SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&); SizeOffsetEvalType visitLoadInst(LoadInst &I); diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp index 6b21b73f22f..b60b728b915 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); } @@ -440,6 +448,11 @@ ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull&) { return std::make_pair(Zero, Zero); } +SizeOffsetType +ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst&) { + return unknown(); +} + SizeOffsetType ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst&) { // Easy cases were already folded by previous passes. @@ -616,6 +629,16 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) { // - memset } +SizeOffsetEvalType +ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst&) { + return unknown(); +} + +SizeOffsetEvalType +ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst&) { + return unknown(); +} + SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) { SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand()); -- 2.34.1