[llvm-branch-commits] [llvm-branch] r226090 - Merging r226029:

Duncan P. N. Exon Smith dexonsmith at apple.com
Wed Jan 14 19:58:02 PST 2015


Author: dexonsmith
Date: Wed Jan 14 21:58:02 2015
New Revision: 226090

URL: http://llvm.org/viewvc/llvm-project?rev=226090&view=rev
Log:
Merging r226029:
------------------------------------------------------------------------
r226029 | dexonsmith | 2015-01-14 11:56:10 -0800 (Wed, 14 Jan 2015) | 7 lines

IR: Fix a use-after-free in RAUW

Happened pretty commonly during `LLVMContext` teardown when `clang -g`
hit an error.  This fixes the use-after-free.  Next I'll clean up
teardown so that it's not RAUW'ing when metadata-tracked values are
deleted (only really causes a problem if the graph is mid-construction
when teardown starts, but it's still unnecessary work).
------------------------------------------------------------------------

Modified:
    llvm/branches/release_36/   (props changed)
    llvm/branches/release_36/lib/IR/Metadata.cpp
    llvm/branches/release_36/unittests/IR/MetadataTest.cpp

Propchange: llvm/branches/release_36/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jan 14 21:58:02 2015
@@ -1,3 +1,3 @@
 /llvm/branches/Apple/Pertwee:110850,110961
 /llvm/branches/type-system-rewrite:133420-134817
-/llvm/trunk:155241,226023
+/llvm/trunk:155241,226023,226029

Modified: llvm/branches/release_36/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_36/lib/IR/Metadata.cpp?rev=226090&r1=226089&r2=226090&view=diff
==============================================================================
--- llvm/branches/release_36/lib/IR/Metadata.cpp (original)
+++ llvm/branches/release_36/lib/IR/Metadata.cpp Wed Jan 14 21:58:02 2015
@@ -167,6 +167,11 @@ void ReplaceableMetadataImpl::replaceAll
     return L.second.second < R.second.second;
   });
   for (const auto &Pair : Uses) {
+    // Check that this Ref hasn't disappeared after RAUW (when updating a
+    // previous Ref).
+    if (!UseMap.count(Pair.first))
+      continue;
+
     OwnerTy Owner = Pair.second.first;
     if (!Owner) {
       // Update unowned tracking references directly.

Modified: llvm/branches/release_36/unittests/IR/MetadataTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_36/unittests/IR/MetadataTest.cpp?rev=226090&r1=226089&r2=226090&view=diff
==============================================================================
--- llvm/branches/release_36/unittests/IR/MetadataTest.cpp (original)
+++ llvm/branches/release_36/unittests/IR/MetadataTest.cpp Wed Jan 14 21:58:02 2015
@@ -484,6 +484,34 @@ TEST_F(ValueAsMetadataTest, UpdatesOnRAU
   EXPECT_TRUE(MD->getValue() == GV1.get());
 }
 
+TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) {
+  // Create a constant.
+  ConstantAsMetadata *CI = ConstantAsMetadata::get(
+      ConstantInt::get(getGlobalContext(), APInt(8, 0)));
+
+  // Create a temporary to prevent nodes from resolving.
+  std::unique_ptr<MDNodeFwdDecl> Temp(MDNode::getTemporary(Context, None));
+
+  // When the first operand of N1 gets reset to nullptr, it'll collide with N2.
+  Metadata *Ops1[] = {CI, CI, Temp.get()};
+  Metadata *Ops2[] = {nullptr, CI, Temp.get()};
+
+  auto *N1 = MDTuple::get(Context, Ops1);
+  auto *N2 = MDTuple::get(Context, Ops2);
+  ASSERT_NE(N1, N2);
+
+  // Tell metadata that the constant is getting deleted.
+  //
+  // After this, N1 will be invalid, so don't touch it.
+  ValueAsMetadata::handleDeletion(CI->getValue());
+  EXPECT_EQ(nullptr, N2->getOperand(0));
+  EXPECT_EQ(nullptr, N2->getOperand(1));
+  EXPECT_EQ(Temp.get(), N2->getOperand(2));
+
+  // Clean up Temp for teardown.
+  Temp->replaceAllUsesWith(nullptr);
+}
+
 typedef MetadataTest TrackingMDRefTest;
 
 TEST_F(TrackingMDRefTest, UpdatesOnRAUW) {





More information about the llvm-branch-commits mailing list