summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJohn Brawn <john.brawn@arm.com>2018-08-24 15:48:30 +0000
committerJohn Brawn <john.brawn@arm.com>2018-08-24 15:48:30 +0000
commit980da83f8417e4af10e78f8992e5e31586563ed7 (patch)
treec87cf84b2935dee7efbfffa68060fbe224bda111 /llvm/lib
parent6cc0e63e2f020961c8262b94ae30a23ef0f030af (diff)
downloadbcm5719-llvm-980da83f8417e4af10e78f8992e5e31586563ed7.tar.gz
bcm5719-llvm-980da83f8417e4af10e78f8992e5e31586563ed7.zip
[PhiValues] Use callback value handles to invalidate deleted values
The way that PhiValues is integrated with BasicAA it is possible for a pass which uses BasicAA to pick up an instance of BasicAA that uses PhiValues without intending to, and then delete values from a function in a way that causes PhiValues to return dangling pointers to these deleted values. Fix this by having a set of callback value handles to invalidate values when they're deleted. llvm-svn: 340613
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/PhiValues.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/PhiValues.cpp b/llvm/lib/Analysis/PhiValues.cpp
index ef121815d2c..729227c8669 100644
--- a/llvm/lib/Analysis/PhiValues.cpp
+++ b/llvm/lib/Analysis/PhiValues.cpp
@@ -14,6 +14,16 @@
using namespace llvm;
+void PhiValues::PhiValuesCallbackVH::deleted() {
+ PV->invalidateValue(getValPtr());
+}
+
+void PhiValues::PhiValuesCallbackVH::allUsesReplacedWith(Value *) {
+ // We could potentially update the cached values we have with the new value,
+ // but it's simpler to just treat the old value as invalidated.
+ PV->invalidateValue(getValPtr());
+}
+
bool PhiValues::invalidate(Function &, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &) {
// PhiValues is invalidated if it isn't preserved.
@@ -46,6 +56,7 @@ void PhiValues::processPhi(const PHINode *Phi,
DepthMap[Phi] = DepthNumber;
// Recursively process the incoming phis of this phi.
+ TrackedValues.insert(PhiValuesCallbackVH(const_cast<PHINode *>(Phi), this));
for (Value *PhiOp : Phi->incoming_values()) {
if (PHINode *PhiPhiOp = dyn_cast<PHINode>(PhiOp)) {
// Recurse if the phi has not yet been visited.
@@ -56,6 +67,8 @@ void PhiValues::processPhi(const PHINode *Phi,
// phi are part of the same component, so adjust the depth number.
if (!ReachableMap.count(DepthMap[PhiPhiOp]))
DepthMap[Phi] = std::min(DepthMap[Phi], DepthMap[PhiPhiOp]);
+ } else {
+ TrackedValues.insert(PhiValuesCallbackVH(PhiOp, this));
}
}
@@ -122,6 +135,10 @@ void PhiValues::invalidateValue(const Value *V) {
NonPhiReachableMap.erase(N);
ReachableMap.erase(N);
}
+ // This value is no longer tracked
+ auto It = TrackedValues.find_as(V);
+ if (It != TrackedValues.end())
+ TrackedValues.erase(It);
}
void PhiValues::releaseMemory() {
OpenPOWER on IntegriCloud