aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/MemoryBuiltins.cpp
diff options
context:
space:
mode:
authorNuno Lopes <nunoplopes@sapo.pt>2012-06-28 16:34:03 +0000
committerNuno Lopes <nunoplopes@sapo.pt>2012-06-28 16:34:03 +0000
commit41a3f251346681e21171879dce409b2e6a3ba750 (patch)
tree0cb88b83a912fb5cbe5f2de1e519f1b5bedb58dd /lib/Analysis/MemoryBuiltins.cpp
parente50487796d49624bf174bd08a86d20fcdbfb45c1 (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.cpp51
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))