mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
IR: Don't track nullptr on metadata RAUW
The RAUW support in `Metadata` supports going to `nullptr` specifically to handle values being deleted, causing `ValueAsMetadata` to be deleted. Fix the case where the reference is from a `TrackingMDRef` (as opposed to an `MDOperand` or a `MetadataAsValue`). This is surprisingly rare -- metadata tracked by `TrackingMDRef` going to null -- but it came up in an openSUSE bootstrap during inlining. The tracking ref was held by the `ValueMap` because it was referencing a local, the basic block containing the local became dead after it had been merged in, and when the local was deleted, the tracking ref asserted in an `isa`. llvm-svn: 224146
This commit is contained in:
parent
8851da85ea
commit
77f50da5c2
@ -173,7 +173,8 @@ void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
|
||||
// Update unowned tracking references directly.
|
||||
Metadata *&Ref = *static_cast<Metadata **>(Pair.first);
|
||||
Ref = MD;
|
||||
MetadataTracking::track(Ref);
|
||||
if (MD)
|
||||
MetadataTracking::track(Ref);
|
||||
UseMap.erase(Pair.first);
|
||||
continue;
|
||||
}
|
||||
|
@ -207,6 +207,53 @@ TEST_F(MetadataAsValueTest, MDNodeConstant) {
|
||||
EXPECT_EQ(V, V2);
|
||||
}
|
||||
|
||||
typedef MetadataTest ValueAsMetadataTest;
|
||||
|
||||
TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) {
|
||||
Type *Ty = Type::getInt1PtrTy(Context);
|
||||
std::unique_ptr<GlobalVariable> GV0(
|
||||
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
|
||||
auto *MD = ValueAsMetadata::get(GV0.get());
|
||||
EXPECT_TRUE(MD->getValue() == GV0.get());
|
||||
ASSERT_TRUE(GV0->use_empty());
|
||||
|
||||
std::unique_ptr<GlobalVariable> GV1(
|
||||
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
|
||||
GV0->replaceAllUsesWith(GV1.get());
|
||||
EXPECT_TRUE(MD->getValue() == GV1.get());
|
||||
}
|
||||
|
||||
typedef MetadataTest TrackingMDRefTest;
|
||||
|
||||
TEST_F(TrackingMDRefTest, UpdatesOnRAUW) {
|
||||
Type *Ty = Type::getInt1PtrTy(Context);
|
||||
std::unique_ptr<GlobalVariable> GV0(
|
||||
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
|
||||
TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV0.get()));
|
||||
EXPECT_TRUE(MD->getValue() == GV0.get());
|
||||
ASSERT_TRUE(GV0->use_empty());
|
||||
|
||||
std::unique_ptr<GlobalVariable> GV1(
|
||||
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
|
||||
GV0->replaceAllUsesWith(GV1.get());
|
||||
EXPECT_TRUE(MD->getValue() == GV1.get());
|
||||
|
||||
// Reset it, so we don't inadvertently test deletion.
|
||||
MD.reset();
|
||||
}
|
||||
|
||||
TEST_F(TrackingMDRefTest, UpdatesOnDeletion) {
|
||||
Type *Ty = Type::getInt1PtrTy(Context);
|
||||
std::unique_ptr<GlobalVariable> GV(
|
||||
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
|
||||
TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV.get()));
|
||||
EXPECT_TRUE(MD->getValue() == GV.get());
|
||||
ASSERT_TRUE(GV->use_empty());
|
||||
|
||||
GV.reset();
|
||||
EXPECT_TRUE(!MD);
|
||||
}
|
||||
|
||||
TEST(NamedMDNodeTest, Search) {
|
||||
LLVMContext Context;
|
||||
ConstantAsMetadata *C =
|
||||
|
Loading…
Reference in New Issue
Block a user