summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp5
-rw-r--r--llvm/lib/IR/Metadata.cpp2
-rw-r--r--llvm/lib/Linker/IRMover.cpp17
3 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 824a3716b83..c7606fd488a 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -3085,6 +3085,11 @@ void BitcodeReader::saveMetadataList(
assert(MetadataToIDs[MD] == ID && "Inconsistent metadata value id");
continue;
}
+ if (N && N->isTemporary())
+ // Ensure that we assert if someone tries to RAUW this temporary
+ // metadata while it is the key of a map. The flag will be set back
+ // to true when the saved metadata list is destroyed.
+ N->setCanReplace(false);
MetadataToIDs[MD] = ID;
}
}
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index ab1ba5e2035..f9543a65858 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -190,6 +190,8 @@ void ReplaceableMetadataImpl::moveRef(void *Ref, void *New,
void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
assert(!(MD && isa<MDNode>(MD) && cast<MDNode>(MD)->isTemporary()) &&
"Expected non-temp node");
+ assert(CanReplace &&
+ "Attempted to replace Metadata marked for no replacement");
if (UseMap.empty())
return;
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index fa6e37517fc..2e09d78a690 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -524,6 +524,23 @@ public:
ValueMapperFlags = ValueMapperFlags | RF_HaveUnmaterializedMetadata;
}
+ ~IRLinker() {
+ // In the case where we are not linking metadata, we unset the CanReplace
+ // flag on all temporary metadata in the MetadataToIDs map to ensure
+ // none was replaced while being a map key. Now that we are destructing
+ // the map, set the flag back to true, so that it is replaceable during
+ // metadata linking.
+ if (!shouldLinkMetadata()) {
+ for (auto MDI : MetadataToIDs) {
+ Metadata *MD = const_cast<Metadata *>(MDI.first);
+ MDNode *Node = dyn_cast<MDNode>(MD);
+ assert((Node && Node->isTemporary()) &&
+ "Found non-temp metadata in map when not linking metadata");
+ Node->setCanReplace(true);
+ }
+ }
+ }
+
bool run();
Value *materializeDeclFor(Value *V, bool ForAlias);
void materializeInitFor(GlobalValue *New, GlobalValue *Old, bool ForAlias);
OpenPOWER on IntegriCloud