summaryrefslogtreecommitdiff
path: root/lib/VMCore/Value.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2012-01-23 00:05:17 +0000
committerNick Lewycky <nicholas@mxc.ca>2012-01-23 00:05:17 +0000
commit37abc488a0527bb682af5aa6c4f376b5b99d67e4 (patch)
tree13d1df3a5e17ba9f525ed60688ff0a9c4d9692d4 /lib/VMCore/Value.cpp
parent1906d32e55224b7481cd9e5726bd5e14b55f5cc1 (diff)
downloadllvm-37abc488a0527bb682af5aa6c4f376b5b99d67e4.tar.gz
llvm-37abc488a0527bb682af5aa6c4f376b5b99d67e4.tar.bz2
llvm-37abc488a0527bb682af5aa6c4f376b5b99d67e4.tar.xz
Make Value::isDereferenceablePointer() handle unreachable code blocks. (This
returns false in the event the computation feeding into the pointer is unreachable, which maybe ought to be true -- but this is at least consistent with undef->isDereferenceablePointer().) Fixes PR11825! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148671 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Value.cpp')
-rw-r--r--lib/VMCore/Value.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index a5f1918e55..207c06d223 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -349,7 +349,8 @@ Value *Value::stripPointerCasts() {
/// isDereferenceablePointer - Test if this value is always a pointer to
/// allocated and suitably aligned memory for a simple load or store.
-bool Value::isDereferenceablePointer() const {
+static bool isDereferenceablePointer(const Value *V,
+ SmallPtrSet<const Value *, 32> &Visited) {
// Note that it is not safe to speculate into a malloc'd region because
// malloc may return null.
// It's also not always safe to follow a bitcast, for example:
@@ -358,20 +359,22 @@ bool Value::isDereferenceablePointer() const {
// be handled using TargetData to check sizes and alignments though.
// These are obviously ok.
- if (isa<AllocaInst>(this)) return true;
+ if (isa<AllocaInst>(V)) return true;
// Global variables which can't collapse to null are ok.
- if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this))
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
return !GV->hasExternalWeakLinkage();
// byval arguments are ok.
- if (const Argument *A = dyn_cast<Argument>(this))
+ if (const Argument *A = dyn_cast<Argument>(V))
return A->hasByValAttr();
-
+
// For GEPs, determine if the indexing lands within the allocated object.
- if (const GEPOperator *GEP = dyn_cast<GEPOperator>(this)) {
+ if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
// Conservatively require that the base pointer be fully dereferenceable.
- if (!GEP->getOperand(0)->isDereferenceablePointer())
+ if (!Visited.insert(GEP->getOperand(0)))
+ return false;
+ if (!isDereferenceablePointer(GEP->getOperand(0), Visited))
return false;
// Check the indices.
gep_type_iterator GTI = gep_type_begin(GEP);
@@ -405,6 +408,13 @@ bool Value::isDereferenceablePointer() const {
return false;
}
+/// isDereferenceablePointer - Test if this value is always a pointer to
+/// allocated and suitably aligned memory for a simple load or store.
+bool Value::isDereferenceablePointer() const {
+ SmallPtrSet<const Value *, 32> Visited;
+ return ::isDereferenceablePointer(this, Visited);
+}
+
/// DoPHITranslation - If this value is a PHI node with CurBB as its parent,
/// return the value in the PHI node corresponding to PredBB. If not, return
/// ourself. This is useful if you want to know the value something has in a