[PATCH] D28749: Fix use-after-free bug in AffectedValueCallbackVH::allUsesReplacedWith

Hal Finkel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 15 14:38:20 PST 2017


hfinkel created this revision.
hfinkel added reviewers: dim, chandlerc.
hfinkel added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.

When transferring affected values in the cache from an old value, identified by the value of the current callback, to the specified new value we might need to insert a new entry into the DenseMap which constitutes the cache. Doing so might delete the current callback object. Move the copying logic into a new function, a member of the assumption cache itself, so that we don't run into UB should the callback handle itself be removed mid-copy.


https://reviews.llvm.org/D28749

Files:
  include/llvm/Analysis/AssumptionCache.h
  lib/Analysis/AssumptionCache.cpp


Index: lib/Analysis/AssumptionCache.cpp
===================================================================
--- lib/Analysis/AssumptionCache.cpp
+++ lib/Analysis/AssumptionCache.cpp
@@ -111,20 +111,25 @@
   // 'this' now dangles!
 }
 
+void AssumptionCache::copyAffectedValuesInCache(Value *OV, Value *NV) {
+  auto &NAVV = getAffectedValues(NV);
+  auto AVI = AffectedValues.find(OV);
+  if (AVI == AffectedValues.end())
+    return;
+
+  for (auto &A : AVI->second)
+    if (std::find(NAVV.begin(), NAVV.end(), A) == NAVV.end())
+      NAVV.push_back(A);
+}
+
 void AssumptionCache::AffectedValueCallbackVH::allUsesReplacedWith(Value *NV) {
   if (!isa<Instruction>(NV) && !isa<Argument>(NV))
     return;
 
   // Any assumptions that affected this value now affect the new value.
 
-  auto &NAVV = AC->getAffectedValues(NV);
-  auto AVI = AC->AffectedValues.find(getValPtr());
-  if (AVI == AC->AffectedValues.end())
-    return;
-
-  for (auto &A : AVI->second)
-    if (std::find(NAVV.begin(), NAVV.end(), A) == NAVV.end())
-      NAVV.push_back(A);
+  AC->copyAffectedValuesInCache(getValPtr(), NV);
+  // 'this' now might dangle!
 }
 
 void AssumptionCache::scanFunction() {
Index: include/llvm/Analysis/AssumptionCache.h
===================================================================
--- include/llvm/Analysis/AssumptionCache.h
+++ include/llvm/Analysis/AssumptionCache.h
@@ -70,6 +70,9 @@
   /// Get the vector of assumptions which affect a value from the cache.
   SmallVector<WeakVH, 1> &getAffectedValues(Value *V);
 
+  /// Copy affected values in the cache for OV to be affected values for NV.
+  void copyAffectedValuesInCache(Value *OV, Value *NV);
+
   /// \brief Flag tracking whether we have scanned the function yet.
   ///
   /// We want to be as lazy about this as possible, and so we scan the function


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28749.84505.patch
Type: text/x-patch
Size: 1830 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170115/935c6e33/attachment.bin>


More information about the llvm-commits mailing list