ValueMapper: Disallow metadata mapping recursion through mapValue

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
This commit is contained in:
Duncan P. N. Exon Smith 2016-04-03 20:54:51 +00:00
parent 283adc2050
commit 9c1df1b42a
2 changed files with 12 additions and 0 deletions

View 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)

View 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;