diff options
Diffstat (limited to 'gnu/llvm/unittests/IR/MetadataTest.cpp')
| -rw-r--r-- | gnu/llvm/unittests/IR/MetadataTest.cpp | 484 |
1 files changed, 311 insertions, 173 deletions
diff --git a/gnu/llvm/unittests/IR/MetadataTest.cpp b/gnu/llvm/unittests/IR/MetadataTest.cpp index a745b235a38..15b03b3d572 100644 --- a/gnu/llvm/unittests/IR/MetadataTest.cpp +++ b/gnu/llvm/unittests/IR/MetadataTest.cpp @@ -80,26 +80,29 @@ protected: MDTuple *getTuple() { return MDTuple::getDistinct(Context, None); } DISubroutineType *getSubroutineType() { - return DISubroutineType::getDistinct(Context, 0, getNode(nullptr)); + return DISubroutineType::getDistinct(Context, 0, 0, getNode(nullptr)); } DISubprogram *getSubprogram() { return DISubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0, - nullptr, false, false, 0, nullptr, 0, 0, 0, - 0); + nullptr, false, false, 0, nullptr, + 0, 0, 0, 0, false, nullptr); } - DIScopeRef getSubprogramRef() { return getSubprogram()->getRef(); } DIFile *getFile() { return DIFile::getDistinct(Context, "file.c", "/path/to/dir"); } - DITypeRef getBasicType(StringRef Name) { - return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name) - ->getRef(); + DICompileUnit *getUnit() { + return DICompileUnit::getDistinct(Context, 1, getFile(), "clang", false, + "-g", 2, "", DICompileUnit::FullDebug, + getTuple(), getTuple(), getTuple(), + getTuple(), getTuple(), 0); } - DITypeRef getDerivedType() { + DIType *getBasicType(StringRef Name) { + return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); + } + DIType *getDerivedType() { return DIDerivedType::getDistinct(Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, - getBasicType("basictype"), 1, 2, 0, 0) - ->getRef(); + getBasicType("basictype"), 1, 2, 0, 0); } Constant *getConstant() { return ConstantInt::get(Type::getInt32Ty(Context), Counter++); @@ -107,11 +110,10 @@ protected: ConstantAsMetadata *getConstantAsMetadata() { return ConstantAsMetadata::get(getConstant()); } - DITypeRef getCompositeType() { + DIType *getCompositeType() { return DICompositeType::getDistinct( - Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, - nullptr, 32, 32, 0, 0, nullptr, 0, nullptr, nullptr, "") - ->getRef(); + Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, nullptr, + 32, 32, 0, 0, nullptr, 0, nullptr, nullptr, ""); } Function *getFunction(StringRef Name) { return cast<Function>(M.getOrInsertFunction( @@ -174,8 +176,8 @@ TEST_F(MDNodeTest, Simple) { MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); - ConstantAsMetadata *CI = ConstantAsMetadata::get( - ConstantInt::get(getGlobalContext(), APInt(8, 0))); + ConstantAsMetadata *CI = + ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); std::vector<Metadata *> V; V.push_back(s1); @@ -206,8 +208,8 @@ TEST_F(MDNodeTest, Simple) { } TEST_F(MDNodeTest, Delete) { - Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1); - Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext())); + Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1); + Instruction *I = new BitCastInst(C, Type::getInt32Ty(Context)); Metadata *const V = LocalAsMetadata::get(I); MDNode *n = MDNode::get(Context, V); @@ -447,6 +449,40 @@ TEST_F(MDNodeTest, DistinctOnUniquingCollision) { EXPECT_FALSE(Wrapped1->isDistinct()); } +TEST_F(MDNodeTest, UniquedOnDeletedOperand) { + // temp !{} + TempMDTuple T = MDTuple::getTemporary(Context, None); + + // !{temp !{}} + Metadata *Ops[] = {T.get()}; + MDTuple *N = MDTuple::get(Context, Ops); + + // !{temp !{}} => !{null} + T.reset(); + ASSERT_TRUE(N->isUniqued()); + Metadata *NullOps[] = {nullptr}; + ASSERT_EQ(N, MDTuple::get(Context, NullOps)); +} + +TEST_F(MDNodeTest, DistinctOnDeletedValueOperand) { + // i1* @GV + Type *Ty = Type::getInt1PtrTy(Context); + std::unique_ptr<GlobalVariable> GV( + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); + ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get()); + + // !{i1* @GV} + Metadata *Ops[] = {Op}; + MDTuple *N = MDTuple::get(Context, Ops); + + // !{i1* @GV} => !{null} + GV.reset(); + ASSERT_TRUE(N->isDistinct()); + ASSERT_EQ(nullptr, N->getOperand(0)); + Metadata *NullOps[] = {nullptr}; + ASSERT_NE(N, MDTuple::get(Context, NullOps)); +} + TEST_F(MDNodeTest, getDistinct) { // !{} MDNode *Empty = MDNode::get(Context, None); @@ -494,20 +530,6 @@ TEST_F(MDNodeTest, isTemporary) { EXPECT_TRUE(T->isTemporary()); } -#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) - -TEST_F(MDNodeTest, deathOnNoReplaceTemporaryRAUW) { - auto Temp = MDNode::getTemporary(Context, None); - Temp->setCanReplace(false); - EXPECT_DEATH(Temp->replaceAllUsesWith(nullptr), - "Attempted to replace Metadata marked for no replacement"); - Temp->setCanReplace(true); - // Remove the references to Temp; required for teardown. - Temp->replaceAllUsesWith(nullptr); -} - -#endif - TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) { // temporary !{} auto Temp = MDTuple::getTemporary(Context, None); @@ -681,7 +703,7 @@ TEST_F(MDNodeTest, replaceWithUniquedResolvingOperand) { EXPECT_TRUE(N->isResolved()); } -TEST_F(MDNodeTest, replaceWithUniquedChangingOperand) { +TEST_F(MDNodeTest, replaceWithUniquedDeletedOperand) { // i1* @GV Type *Ty = Type::getInt1PtrTy(Context); std::unique_ptr<GlobalVariable> GV( @@ -698,8 +720,33 @@ TEST_F(MDNodeTest, replaceWithUniquedChangingOperand) { // !{i1* @GV} => !{null} GV.reset(); - ASSERT_TRUE(N->isUniqued()); + ASSERT_TRUE(N->isDistinct()); + ASSERT_EQ(nullptr, N->getOperand(0)); Metadata *NullOps[] = {nullptr}; + ASSERT_NE(N, MDTuple::get(Context, NullOps)); +} + +TEST_F(MDNodeTest, replaceWithUniquedChangedOperand) { + // i1* @GV + Type *Ty = Type::getInt1PtrTy(Context); + std::unique_ptr<GlobalVariable> GV( + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); + ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get()); + + // temp !{i1* @GV} + Metadata *Ops[] = {Op}; + MDTuple *N = MDTuple::getTemporary(Context, Ops).release(); + + // temp !{i1* @GV} => !{i1* @GV} + ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N))); + ASSERT_TRUE(N->isUniqued()); + + // !{i1* @GV} => !{i1* @GV2} + std::unique_ptr<GlobalVariable> GV2( + new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); + GV->replaceAllUsesWith(GV2.get()); + ASSERT_TRUE(N->isUniqued()); + Metadata *NullOps[] = {ConstantAsMetadata::get(GV2.get())}; ASSERT_EQ(N, MDTuple::get(Context, NullOps)); } @@ -981,14 +1028,14 @@ TEST_F(DITypeTest, setFlags) { Metadata *TypesOps[] = {nullptr}; Metadata *Types = MDTuple::get(Context, TypesOps); - DIType *D = DISubroutineType::getDistinct(Context, 0u, Types); + DIType *D = DISubroutineType::getDistinct(Context, 0u, 0, Types); EXPECT_EQ(0u, D->getFlags()); D->setFlags(DINode::FlagRValueReference); EXPECT_EQ(DINode::FlagRValueReference, D->getFlags()); D->setFlags(0u); EXPECT_EQ(0u, D->getFlags()); - TempDIType T = DISubroutineType::getTemporary(Context, 0u, Types); + TempDIType T = DISubroutineType::getTemporary(Context, 0u, 0, Types); EXPECT_EQ(0u, T->getFlags()); T->setFlags(DINode::FlagRValueReference); EXPECT_EQ(DINode::FlagRValueReference, T->getFlags()); @@ -1000,8 +1047,8 @@ typedef MetadataTest DIDerivedTypeTest; TEST_F(DIDerivedTypeTest, get) { DIFile *File = getFile(); - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getBasicType("basic"); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getBasicType("basic"); MDTuple *ExtraData = getTuple(); auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", @@ -1034,7 +1081,7 @@ TEST_F(DIDerivedTypeTest, get) { "something", File, 2, Scope, BaseType, 2, 3, 4, 5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, - "something", File, 1, getSubprogramRef(), + "something", File, 1, getSubprogram(), BaseType, 2, 3, 4, 5, ExtraData)); EXPECT_NE(N, DIDerivedType::get( Context, dwarf::DW_TAG_pointer_type, "something", File, 1, @@ -1061,8 +1108,8 @@ TEST_F(DIDerivedTypeTest, get) { TEST_F(DIDerivedTypeTest, getWithLargeValues) { DIFile *File = getFile(); - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getBasicType("basic"); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getBasicType("basic"); MDTuple *ExtraData = getTuple(); auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", @@ -1080,15 +1127,15 @@ TEST_F(DICompositeTypeTest, get) { StringRef Name = "some name"; DIFile *File = getFile(); unsigned Line = 1; - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getCompositeType(); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getCompositeType(); uint64_t SizeInBits = 2; uint64_t AlignInBits = 3; uint64_t OffsetInBits = 4; unsigned Flags = 5; MDTuple *Elements = getTuple(); unsigned RuntimeLang = 6; - DITypeRef VTableHolder = getCompositeType(); + DIType *VTableHolder = getCompositeType(); MDTuple *TemplateParams = getTuple(); StringRef Identifier = "some id"; @@ -1134,7 +1181,7 @@ TEST_F(DICompositeTypeTest, get) { OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get( - Context, Tag, Name, File, Line, getSubprogramRef(), BaseType, + Context, Tag, Name, File, Line, getSubprogram(), BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get( @@ -1199,15 +1246,15 @@ TEST_F(DICompositeTypeTest, getWithLargeValues) { StringRef Name = "some name"; DIFile *File = getFile(); unsigned Line = 1; - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getCompositeType(); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getCompositeType(); uint64_t SizeInBits = UINT64_MAX; uint64_t AlignInBits = UINT64_MAX - 1; uint64_t OffsetInBits = UINT64_MAX - 2; unsigned Flags = 5; MDTuple *Elements = getTuple(); unsigned RuntimeLang = 6; - DITypeRef VTableHolder = getCompositeType(); + DIType *VTableHolder = getCompositeType(); MDTuple *TemplateParams = getTuple(); StringRef Identifier = "some id"; @@ -1225,8 +1272,8 @@ TEST_F(DICompositeTypeTest, replaceOperands) { StringRef Name = "some name"; DIFile *File = getFile(); unsigned Line = 1; - DIScopeRef Scope = getSubprogramRef(); - DITypeRef BaseType = getCompositeType(); + DIScope *Scope = getSubprogram(); + DIType *BaseType = getCompositeType(); uint64_t SizeInBits = 2; uint64_t AlignInBits = 3; uint64_t OffsetInBits = 4; @@ -1245,7 +1292,7 @@ TEST_F(DICompositeTypeTest, replaceOperands) { N->replaceElements(nullptr); EXPECT_EQ(nullptr, N->getElements().get()); - DITypeRef VTableHolder = getCompositeType(); + DIType *VTableHolder = getCompositeType(); EXPECT_EQ(nullptr, N->getVTableHolder()); N->replaceVTableHolder(VTableHolder); EXPECT_EQ(VTableHolder, N->getVTableHolder()); @@ -1266,14 +1313,29 @@ TEST_F(DISubroutineTypeTest, get) { unsigned Flags = 1; MDTuple *TypeArray = getTuple(); - auto *N = DISubroutineType::get(Context, Flags, TypeArray); + auto *N = DISubroutineType::get(Context, Flags, 0, TypeArray); EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag()); EXPECT_EQ(Flags, N->getFlags()); EXPECT_EQ(TypeArray, N->getTypeArray().get()); - EXPECT_EQ(N, DISubroutineType::get(Context, Flags, TypeArray)); - - EXPECT_NE(N, DISubroutineType::get(Context, Flags + 1, TypeArray)); - EXPECT_NE(N, DISubroutineType::get(Context, Flags, getTuple())); + EXPECT_EQ(N, DISubroutineType::get(Context, Flags, 0, TypeArray)); + + EXPECT_NE(N, DISubroutineType::get(Context, Flags + 1, 0, TypeArray)); + EXPECT_NE(N, DISubroutineType::get(Context, Flags, 0, getTuple())); + + // Test the hashing of calling conventions. + auto *Fast = DISubroutineType::get( + Context, Flags, dwarf::DW_CC_BORLAND_msfastcall, TypeArray); + auto *Std = DISubroutineType::get(Context, Flags, + dwarf::DW_CC_BORLAND_stdcall, TypeArray); + EXPECT_EQ(Fast, + DISubroutineType::get(Context, Flags, + dwarf::DW_CC_BORLAND_msfastcall, TypeArray)); + EXPECT_EQ(Std, DISubroutineType::get( + Context, Flags, dwarf::DW_CC_BORLAND_stdcall, TypeArray)); + + EXPECT_NE(N, Fast); + EXPECT_NE(N, Std); + EXPECT_NE(Fast, Std); TempDISubroutineType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -1319,10 +1381,9 @@ TEST_F(DICompileUnitTest, get) { StringRef Flags = "flag after flag"; unsigned RuntimeVersion = 2; StringRef SplitDebugFilename = "another/file"; - unsigned EmissionKind = 3; + auto EmissionKind = DICompileUnit::FullDebug; MDTuple *EnumTypes = getTuple(); MDTuple *RetainedTypes = getTuple(); - MDTuple *Subprograms = getTuple(); MDTuple *GlobalVariables = getTuple(); MDTuple *ImportedEntities = getTuple(); uint64_t DWOId = 0x10000000c0ffee; @@ -1330,7 +1391,7 @@ TEST_F(DICompileUnitTest, get) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, Macros, + RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId); EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); @@ -1344,7 +1405,6 @@ TEST_F(DICompileUnitTest, get) { EXPECT_EQ(EmissionKind, N->getEmissionKind()); EXPECT_EQ(EnumTypes, N->getEnumTypes().get()); EXPECT_EQ(RetainedTypes, N->getRetainedTypes().get()); - EXPECT_EQ(Subprograms, N->getSubprograms().get()); EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get()); EXPECT_EQ(ImportedEntities, N->getImportedEntities().get()); EXPECT_EQ(Macros, N->getMacros().get()); @@ -1362,7 +1422,6 @@ TEST_F(DICompileUnitTest, get) { EXPECT_EQ(EmissionKind, Temp->getEmissionKind()); EXPECT_EQ(EnumTypes, Temp->getEnumTypes().get()); EXPECT_EQ(RetainedTypes, Temp->getRetainedTypes().get()); - EXPECT_EQ(Subprograms, Temp->getSubprograms().get()); EXPECT_EQ(GlobalVariables, Temp->getGlobalVariables().get()); EXPECT_EQ(ImportedEntities, Temp->getImportedEntities().get()); EXPECT_EQ(Macros, Temp->getMacros().get()); @@ -1382,7 +1441,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { StringRef Flags = "flag after flag"; unsigned RuntimeVersion = 2; StringRef SplitDebugFilename = "another/file"; - unsigned EmissionKind = 3; + auto EmissionKind = DICompileUnit::FullDebug; MDTuple *EnumTypes = MDTuple::getDistinct(Context, None); MDTuple *RetainedTypes = MDTuple::getDistinct(Context, None); MDTuple *ImportedEntities = MDTuple::getDistinct(Context, None); @@ -1390,14 +1449,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, nullptr, nullptr, ImportedEntities, nullptr, DWOId); - - auto *Subprograms = MDTuple::getDistinct(Context, None); - EXPECT_EQ(nullptr, N->getSubprograms().get()); - N->replaceSubprograms(Subprograms); - EXPECT_EQ(Subprograms, N->getSubprograms().get()); - N->replaceSubprograms(nullptr); - EXPECT_EQ(nullptr, N->getSubprograms().get()); + RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId); auto *GlobalVariables = MDTuple::getDistinct(Context, None); EXPECT_EQ(nullptr, N->getGlobalVariables().get()); @@ -1417,7 +1469,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { typedef MetadataTest DISubprogramTest; TEST_F(DISubprogramTest, get) { - DIScopeRef Scope = getCompositeType(); + DIScope *Scope = getCompositeType(); StringRef Name = "name"; StringRef LinkageName = "linkage"; DIFile *File = getFile(); @@ -1426,19 +1478,23 @@ TEST_F(DISubprogramTest, get) { bool IsLocalToUnit = false; bool IsDefinition = true; unsigned ScopeLine = 3; - DITypeRef ContainingType = getCompositeType(); - unsigned Virtuality = 4; + DIType *ContainingType = getCompositeType(); + unsigned Virtuality = 2; unsigned VirtualIndex = 5; + int ThisAdjustment = -3; unsigned Flags = 6; + unsigned NotFlags = (~Flags) & ((1 << 27) - 1); bool IsOptimized = false; MDTuple *TemplateParams = getTuple(); DISubprogram *Declaration = getSubprogram(); MDTuple *Variables = getTuple(); + DICompileUnit *Unit = getUnit(); - auto *N = DISubprogram::get( - Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, - IsOptimized, TemplateParams, Declaration, Variables); + auto *N = DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, + ContainingType, Virtuality, VirtualIndex, + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables); EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -1453,102 +1509,110 @@ TEST_F(DISubprogramTest, get) { EXPECT_EQ(ContainingType, N->getContainingType()); EXPECT_EQ(Virtuality, N->getVirtuality()); EXPECT_EQ(VirtualIndex, N->getVirtualIndex()); + EXPECT_EQ(ThisAdjustment, N->getThisAdjustment()); EXPECT_EQ(Flags, N->getFlags()); EXPECT_EQ(IsOptimized, N->isOptimized()); + EXPECT_EQ(Unit, N->getUnit()); EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); EXPECT_EQ(Declaration, N->getDeclaration()); EXPECT_EQ(Variables, N->getVariables().get()); EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); - - EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName, - File, Line, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, - TemplateParams, Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File, - Line, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, + ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)); + + EXPECT_NE(N, DISubprogram::get( + Context, getCompositeType(), Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get( + Context, Scope, "other", LinkageName, File, Line, Type, + IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(), - Line, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, - TemplateParams, Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, - Line + 1, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, - TemplateParams, Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - getSubroutineType(), IsLocalToUnit, - IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, Flags, IsOptimized, + ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get( + Context, Scope, Name, LinkageName, getFile(), Line, Type, + IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get( + Context, Scope, Name, LinkageName, File, Line + 1, Type, + IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, + DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + getSubroutineType(), IsLocalToUnit, IsDefinition, + ScopeLine, ContainingType, Virtuality, + VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, !IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, !IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, - ScopeLine + 1, ContainingType, Virtuality, - VirtualIndex, Flags, IsOptimized, + ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get( + Context, Scope, Name, LinkageName, File, Line, Type, + IsLocalToUnit, IsDefinition, ScopeLine + 1, ContainingType, + Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, + Unit, TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, getCompositeType(), Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality + 1, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex + 1, - Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - ~Flags, IsOptimized, TemplateParams, - Declaration, Variables)); + ThisAdjustment, NotFlags, IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, !IsOptimized, TemplateParams, - Declaration, Variables)); - EXPECT_NE(N, - DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, Flags, - IsOptimized, getTuple(), Declaration, Variables)); + ThisAdjustment, Flags, !IsOptimized, Unit, + TemplateParams, Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - getSubprogram(), Variables)); + ThisAdjustment, Flags, IsOptimized, nullptr, + TemplateParams, Declaration, Variables)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, + ContainingType, Virtuality, VirtualIndex, + ThisAdjustment, Flags, IsOptimized, Unit, + getTuple(), Declaration, Variables)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - Flags, IsOptimized, TemplateParams, - Declaration, getTuple())); + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, getSubprogram(), Variables)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, ScopeLine, + ContainingType, Virtuality, VirtualIndex, + ThisAdjustment, Flags, IsOptimized, Unit, + TemplateParams, Declaration, getTuple())); TempDISubprogram Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -1697,7 +1761,7 @@ typedef MetadataTest DITemplateTypeParameterTest; TEST_F(DITemplateTypeParameterTest, get) { StringRef Name = "template"; - DITypeRef Type = getBasicType("basic"); + DIType *Type = getBasicType("basic"); auto *N = DITemplateTypeParameter::get(Context, Name, Type); @@ -1719,7 +1783,7 @@ typedef MetadataTest DITemplateValueParameterTest; TEST_F(DITemplateValueParameterTest, get) { unsigned Tag = dwarf::DW_TAG_template_value_parameter; StringRef Name = "template"; - DITypeRef Type = getBasicType("basic"); + DIType *Type = getBasicType("basic"); Metadata *Value = getConstantAsMetadata(); auto *N = DITemplateValueParameter::get(Context, Tag, Name, Type, Value); @@ -1751,7 +1815,7 @@ TEST_F(DIGlobalVariableTest, get) { StringRef LinkageName = "linkage"; DIFile *File = getFile(); unsigned Line = 5; - DITypeRef Type = getDerivedType(); + DIType *Type = getDerivedType(); bool IsLocalToUnit = false; bool IsDefinition = true; Constant *Variable = getConstant(); @@ -1824,9 +1888,10 @@ TEST_F(DILocalVariableTest, get) { StringRef Name = "name"; DIFile *File = getFile(); unsigned Line = 5; - DITypeRef Type = getDerivedType(); + DIType *Type = getDerivedType(); unsigned Arg = 6; unsigned Flags = 7; + unsigned NotFlags = (~Flags) & ((1 << 16) - 1); auto *N = DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, Flags); @@ -1857,7 +1922,7 @@ TEST_F(DILocalVariableTest, get) { EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg + 1, Flags)); EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, - ~Flags)); + NotFlags)); TempDILocalVariable Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -1943,7 +2008,7 @@ TEST_F(DIObjCPropertyTest, get) { StringRef GetterName = "getter"; StringRef SetterName = "setter"; unsigned Attributes = 7; - DITypeRef Type = getBasicType("basic"); + DIType *Type = getBasicType("basic"); auto *N = DIObjCProperty::get(Context, Name, File, Line, GetterName, SetterName, Attributes, Type); @@ -1984,7 +2049,7 @@ typedef MetadataTest DIImportedEntityTest; TEST_F(DIImportedEntityTest, get) { unsigned Tag = dwarf::DW_TAG_imported_module; DIScope *Scope = getSubprogram(); - DINodeRef Entity = getCompositeType(); + DINode *Entity = getCompositeType(); unsigned Line = 5; StringRef Name = "name"; @@ -2073,10 +2138,27 @@ TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) { EXPECT_TRUE(MD->getValue() == GV1.get()); } +TEST_F(ValueAsMetadataTest, TempTempReplacement) { + // Create a constant. + ConstantAsMetadata *CI = + ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); + + auto Temp1 = MDTuple::getTemporary(Context, None); + auto Temp2 = MDTuple::getTemporary(Context, {CI}); + auto *N = MDTuple::get(Context, {Temp1.get()}); + + // Test replacing a temporary node with another temporary node. + Temp1->replaceAllUsesWith(Temp2.get()); + EXPECT_EQ(N->getOperand(0), Temp2.get()); + + // Clean up Temp2 for teardown. + Temp2->replaceAllUsesWith(nullptr); +} + TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) { // Create a constant. - ConstantAsMetadata *CI = ConstantAsMetadata::get( - ConstantInt::get(getGlobalContext(), APInt(8, 0))); + ConstantAsMetadata *CI = + ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); // Create a temporary to prevent nodes from resolving. auto Temp = MDTuple::getTemporary(Context, None); @@ -2238,44 +2320,23 @@ TEST_F(FunctionAttachmentTest, getAll) { EXPECT_EQ(T2, MDs[3].second); } -TEST_F(FunctionAttachmentTest, dropUnknownMetadata) { - Function *F = getFunction("foo"); - - MDTuple *T1 = getTuple(); - MDTuple *T2 = getTuple(); - MDTuple *P = getTuple(); - DISubprogram *SP = getSubprogram(); - - F->setMetadata("other1", T1); - F->setMetadata(LLVMContext::MD_dbg, SP); - F->setMetadata("other2", T2); - F->setMetadata(LLVMContext::MD_prof, P); - - unsigned Known[] = {Context.getMDKindID("other2"), LLVMContext::MD_prof}; - F->dropUnknownMetadata(Known); - - EXPECT_EQ(T2, F->getMetadata("other2")); - EXPECT_EQ(P, F->getMetadata(LLVMContext::MD_prof)); - EXPECT_EQ(nullptr, F->getMetadata("other1")); - EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg)); - - F->setMetadata("other2", nullptr); - F->setMetadata(LLVMContext::MD_prof, nullptr); - EXPECT_FALSE(F->hasMetadata()); -} - TEST_F(FunctionAttachmentTest, Verifier) { Function *F = getFunction("foo"); F->setMetadata("attach", getTuple()); + F->setIsMaterializable(true); - // Confirm this has no body. - ASSERT_TRUE(F->empty()); + // Confirm this is materializable. + ASSERT_TRUE(F->isMaterializable()); - // Functions without a body cannot have metadata attachments (they also can't - // be verified directly, so check that the module fails to verify). - EXPECT_TRUE(verifyModule(*F->getParent())); + // Materializable functions cannot have metadata attachments. + EXPECT_TRUE(verifyFunction(*F)); - // Functions with a body can. + // Function declarations can. + F->setIsMaterializable(false); + EXPECT_FALSE(verifyModule(*F->getParent())); + EXPECT_FALSE(verifyFunction(*F)); + + // So can definitions. (void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F)); EXPECT_FALSE(verifyModule(*F->getParent())); EXPECT_FALSE(verifyFunction(*F)); @@ -2301,4 +2362,81 @@ TEST_F(FunctionAttachmentTest, SubprogramAttachment) { EXPECT_EQ(SP, F->getMetadata(LLVMContext::MD_dbg)); } +typedef MetadataTest DistinctMDOperandPlaceholderTest; +TEST_F(DistinctMDOperandPlaceholderTest, getID) { + EXPECT_EQ(7u, DistinctMDOperandPlaceholder(7).getID()); +} + +TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWith) { + // Set up some placeholders. + DistinctMDOperandPlaceholder PH0(7); + DistinctMDOperandPlaceholder PH1(3); + DistinctMDOperandPlaceholder PH2(0); + Metadata *Ops[] = {&PH0, &PH1, &PH2}; + auto *D = MDTuple::getDistinct(Context, Ops); + ASSERT_EQ(&PH0, D->getOperand(0)); + ASSERT_EQ(&PH1, D->getOperand(1)); + ASSERT_EQ(&PH2, D->getOperand(2)); + + // Replace them. + auto *N0 = MDTuple::get(Context, None); + auto *N1 = MDTuple::get(Context, N0); + PH0.replaceUseWith(N0); + PH1.replaceUseWith(N1); + PH2.replaceUseWith(nullptr); + EXPECT_EQ(N0, D->getOperand(0)); + EXPECT_EQ(N1, D->getOperand(1)); + EXPECT_EQ(nullptr, D->getOperand(2)); +} + +TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWithNoUser) { + // There is no user, but we can still call replace. + DistinctMDOperandPlaceholder(7).replaceUseWith(MDTuple::get(Context, None)); } + +#ifndef NDEBUG +#ifdef GTEST_HAS_DEATH_TEST +TEST_F(DistinctMDOperandPlaceholderTest, MetadataAsValue) { + // This shouldn't crash. + DistinctMDOperandPlaceholder PH(7); + EXPECT_DEATH(MetadataAsValue::get(Context, &PH), + "Unexpected callback to owner"); +} + +TEST_F(DistinctMDOperandPlaceholderTest, UniquedMDNode) { + // This shouldn't crash. + DistinctMDOperandPlaceholder PH(7); + EXPECT_DEATH(MDTuple::get(Context, &PH), "Unexpected callback to owner"); +} + +TEST_F(DistinctMDOperandPlaceholderTest, SecondDistinctMDNode) { + // This shouldn't crash. + DistinctMDOperandPlaceholder PH(7); + MDTuple::getDistinct(Context, &PH); + EXPECT_DEATH(MDTuple::getDistinct(Context, &PH), + "Placeholders can only be used once"); +} + +TEST_F(DistinctMDOperandPlaceholderTest, TrackingMDRefAndDistinctMDNode) { + // TrackingMDRef doesn't install an owner callback, so it can't be detected + // as an invalid use. However, using a placeholder in a TrackingMDRef *and* + // a distinct node isn't possible and we should assert. + // + // (There's no positive test for using TrackingMDRef because it's not a + // useful thing to do.) + { + DistinctMDOperandPlaceholder PH(7); + MDTuple::getDistinct(Context, &PH); + EXPECT_DEATH(TrackingMDRef Ref(&PH), "Placeholders can only be used once"); + } + { + DistinctMDOperandPlaceholder PH(7); + TrackingMDRef Ref(&PH); + EXPECT_DEATH(MDTuple::getDistinct(Context, &PH), + "Placeholders can only be used once"); + } +} +#endif +#endif + +} // end namespace |
