diff options
author | Chris Lattner <sabre@nondot.org> | 2011-01-24 03:18:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2011-01-24 03:18:24 +0000 |
commit | 51e62f0f73b2d2a32c2a5b98402114e4c71dc14f (patch) | |
tree | b537bdf19fc4fd1d0dfe75e12633500bb57b2dfe | |
parent | 96c0771c01f4a7858a3a15919d70a1b1ab8f6ac1 (diff) |
fix PR9015, a crash linking recursive metadata.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124099 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Utils/ValueMapper.cpp | 17 | ||||
-rw-r--r-- | test/Linker/linkmdnode.ll | 1 | ||||
-rw-r--r-- | test/Linker/linkmdnode2.ll | 10 |
3 files changed, 22 insertions, 6 deletions
diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index 132c392039..f5481d31eb 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -38,15 +38,16 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, if (!MD->isFunctionLocal() && (Flags & RF_NoModuleLevelChanges)) return VM[V] = const_cast<Value*>(V); + // Create a dummy node in case we have a metadata cycle. + MDNode *Dummy = MDNode::getTemporary(V->getContext(), 0, 0); + VM[V] = Dummy; + // Check all operands to see if any need to be remapped. for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) { Value *OP = MD->getOperand(i); if (OP == 0 || MapValue(OP, VM, Flags) == OP) continue; - // Ok, at least one operand needs remapping. Create a dummy node in case - // we have a metadata cycle. - MDNode *Dummy = MDNode::getTemporary(V->getContext(), 0, 0); - VM[V] = Dummy; + // Ok, at least one operand needs remapping. SmallVector<Value*, 4> Elts; Elts.reserve(MD->getNumOperands()); for (i = 0; i != e; ++i) { @@ -55,12 +56,16 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, } MDNode *NewMD = MDNode::get(V->getContext(), Elts.data(), Elts.size()); Dummy->replaceAllUsesWith(NewMD); + VM[V] = NewMD; MDNode::deleteTemporary(Dummy); - return VM[V] = NewMD; + return NewMD; } + VM[V] = const_cast<Value*>(V); + MDNode::deleteTemporary(Dummy); + // No operands needed remapping. Use an identity mapping. - return VM[V] = const_cast<Value*>(V); + return const_cast<Value*>(V); } // Okay, this either must be a constant (which may or may not be mappable) or diff --git a/test/Linker/linkmdnode.ll b/test/Linker/linkmdnode.ll index be7455056c..5f1158039f 100644 --- a/test/Linker/linkmdnode.ll +++ b/test/Linker/linkmdnode.ll @@ -10,3 +10,4 @@ define void @foo() { %x = call i8 @llvm.something(metadata !21) ret void } + diff --git a/test/Linker/linkmdnode2.ll b/test/Linker/linkmdnode2.ll index 54a5a578b6..a7d991a8a4 100644 --- a/test/Linker/linkmdnode2.ll +++ b/test/Linker/linkmdnode2.ll @@ -10,3 +10,13 @@ define void @foo1() { %x = call i8 @llvm.something(metadata !22) ret void } + + + +; PR9015 +define void @test() { + ret void, !abc !0 +} + +!0 = metadata !{metadata !0, i32 42 } + |