ValueMapper: Disallow metadata mapping recursion through mapValue
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sun, 3 Apr 2016 20:54:51 +0000 (20:54 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sun, 3 Apr 2016 20:54:51 +0000 (20:54 +0000)
This adds an assertion to maintain the property from r265273.  When
Mapper::mapSimpleMetadata calls Mapper::mapValue, it should not find its
way back to mapMetadataImpl.  This guarantees that mapSimpleMetadata is
not involved in any recursion.

Since Mapper::mapValue calls out to arbitrary materializers, we need to
save a bit on the ValueMap to make this assertion effective.

There should be no functionality change here.  This co-recursion should
already have been impossible.

llvm-svn: 265276

llvm/include/llvm/IR/ValueMap.h
llvm/lib/Transforms/Utils/ValueMapper.cpp

index 3425120..0633829 100644 (file)
@@ -87,6 +87,9 @@ class ValueMap {
   MapT Map;
   std::unique_ptr<MDMapT> MDMap;
   ExtraData Data;
+
+  bool MayMapMetadata = true;
+
   ValueMap(const ValueMap&) = delete;
   ValueMap& operator=(const ValueMap&) = delete;
 public:
@@ -107,6 +110,10 @@ public:
     return *MDMap;
   }
 
+  bool mayMapMetadata() const { return MayMapMetadata; }
+  void enableMapMetadata() { MayMapMetadata = true; }
+  void disableMapMetadata() { MayMapMetadata = false; }
+
   /// Get the mapped metadata, if it's in the map.
   Optional<Metadata *> getMappedMD(const Metadata *MD) const {
     if (!MDMap)
index 64ba98e..78f4618 100644 (file)
@@ -379,7 +379,11 @@ Optional<Metadata *> Mapper::mapSimpleMetadata(const Metadata *MD) {
       return mapToSelf(MD);
 
   if (const auto *VMD = dyn_cast<ValueAsMetadata>(MD)) {
+    // Disallow recursion into metadata mapping through mapValue.
+    VM.disableMapMetadata();
     Value *MappedV = mapValue(VMD->getValue());
+    VM.enableMapMetadata();
+
     if (VMD->getValue() == MappedV ||
         (!MappedV && (Flags & RF_IgnoreMissingEntries)))
       return mapToSelf(MD);
@@ -406,6 +410,7 @@ Optional<Metadata *> Mapper::mapSimpleMetadata(const Metadata *MD) {
 }
 
 Metadata *Mapper::mapMetadataImpl(const Metadata *MD) {
+  assert(VM.mayMapMetadata() && "Unexpected co-recursion through mapValue");
   if (Optional<Metadata *> NewMD = mapSimpleMetadata(MD))
     return *NewMD;