diff options
Diffstat (limited to 'unittests/IR')
-rw-r--r-- | unittests/IR/AttributesTest.cpp | 20 | ||||
-rw-r--r-- | unittests/IR/FunctionTest.cpp | 21 | ||||
-rw-r--r-- | unittests/IR/IRBuilderTest.cpp | 22 | ||||
-rw-r--r-- | unittests/IR/InstructionsTest.cpp | 167 | ||||
-rw-r--r-- | unittests/IR/LegacyPassManagerTest.cpp | 17 | ||||
-rw-r--r-- | unittests/IR/MetadataTest.cpp | 49 | ||||
-rw-r--r-- | unittests/IR/ValueHandleTest.cpp | 93 | ||||
-rw-r--r-- | unittests/IR/ValueTest.cpp | 2 | ||||
-rw-r--r-- | unittests/IR/VerifierTest.cpp | 6 |
9 files changed, 351 insertions, 46 deletions
diff --git a/unittests/IR/AttributesTest.cpp b/unittests/IR/AttributesTest.cpp index 9f8013ff181cd..b5b221c63a173 100644 --- a/unittests/IR/AttributesTest.cpp +++ b/unittests/IR/AttributesTest.cpp @@ -21,13 +21,11 @@ TEST(Attributes, Uniquing) { Attribute AttrB = Attribute::get(C, Attribute::AlwaysInline); EXPECT_EQ(AttrA, AttrB); - AttributeSet ASs[] = { - AttributeSet::get(C, 1, Attribute::ZExt), - AttributeSet::get(C, 2, Attribute::SExt) - }; + AttributeList ASs[] = {AttributeList::get(C, 1, Attribute::ZExt), + AttributeList::get(C, 2, Attribute::SExt)}; - AttributeSet SetA = AttributeSet::get(C, ASs); - AttributeSet SetB = AttributeSet::get(C, ASs); + AttributeList SetA = AttributeList::get(C, ASs); + AttributeList SetB = AttributeList::get(C, ASs); EXPECT_EQ(SetA, SetB); } @@ -43,13 +41,11 @@ TEST(Attributes, Ordering) { EXPECT_TRUE(Align4 < Deref5); EXPECT_TRUE(Align5 < Deref4); - AttributeSet ASs[] = { - AttributeSet::get(C, 2, Attribute::ZExt), - AttributeSet::get(C, 1, Attribute::SExt) - }; + AttributeList ASs[] = {AttributeList::get(C, 2, Attribute::ZExt), + AttributeList::get(C, 1, Attribute::SExt)}; - AttributeSet SetA = AttributeSet::get(C, ASs); - AttributeSet SetB = SetA.removeAttributes(C, 1, ASs[1]); + AttributeList SetA = AttributeList::get(C, ASs); + AttributeList SetB = SetA.removeAttributes(C, 1, ASs[1]); EXPECT_NE(SetA, SetB); } diff --git a/unittests/IR/FunctionTest.cpp b/unittests/IR/FunctionTest.cpp index fb458597c37a4..6838d7e2527ff 100644 --- a/unittests/IR/FunctionTest.cpp +++ b/unittests/IR/FunctionTest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" #include "gtest/gtest.h" using namespace llvm; @@ -109,4 +110,24 @@ TEST(FunctionTest, stealArgumentListFrom) { EXPECT_TRUE(F2->hasLazyArguments()); } +// Test setting and removing section information +TEST(FunctionTest, setSection) { + LLVMContext C; + Module M("test", C); + + llvm::Function *F = + Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C), false), + llvm::GlobalValue::ExternalLinkage, "F", &M); + + F->setSection(".text.test"); + EXPECT_TRUE(F->getSection() == ".text.test"); + EXPECT_TRUE(F->hasSection()); + F->setSection(""); + EXPECT_FALSE(F->hasSection()); + F->setSection(".text.test"); + F->setSection(".text.test2"); + EXPECT_TRUE(F->getSection() == ".text.test2"); + EXPECT_TRUE(F->hasSection()); +} + } // end namespace diff --git a/unittests/IR/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp index 1812cd39d135c..830ae9587691c 100644 --- a/unittests/IR/IRBuilderTest.cpp +++ b/unittests/IR/IRBuilderTest.cpp @@ -207,7 +207,26 @@ TEST_F(IRBuilderTest, FastMathFlags) { EXPECT_TRUE(FCmp->hasAllowReciprocal()); Builder.clearFastMathFlags(); - + + // Test FP-contract + FC = Builder.CreateFAdd(F, F); + ASSERT_TRUE(isa<Instruction>(FC)); + FAdd = cast<Instruction>(FC); + EXPECT_FALSE(FAdd->hasAllowContract()); + + FMF.clear(); + FMF.setAllowContract(true); + Builder.setFastMathFlags(FMF); + + FC = Builder.CreateFAdd(F, F); + EXPECT_TRUE(Builder.getFastMathFlags().any()); + EXPECT_TRUE(Builder.getFastMathFlags().AllowContract); + ASSERT_TRUE(isa<Instruction>(FC)); + FAdd = cast<Instruction>(FC); + EXPECT_TRUE(FAdd->hasAllowContract()); + + Builder.clearFastMathFlags(); + // Test a call with FMF. auto CalleeTy = FunctionType::get(Type::getFloatTy(Ctx), /*isVarArg=*/false); @@ -245,6 +264,7 @@ TEST_F(IRBuilderTest, FastMathFlags) { EXPECT_FALSE(FDiv->getFastMathFlags().any()); FDiv->setHasAllowReciprocal(true); FAdd->setHasAllowReciprocal(false); + FAdd->setHasNoNaNs(true); FDiv->copyFastMathFlags(FAdd); EXPECT_TRUE(FDiv->hasNoNaNs()); EXPECT_FALSE(FDiv->hasAllowReciprocal()); diff --git a/unittests/IR/InstructionsTest.cpp b/unittests/IR/InstructionsTest.cpp index 0dac7c1bcfb11..7c75aaec17539 100644 --- a/unittests/IR/InstructionsTest.cpp +++ b/unittests/IR/InstructionsTest.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" +#include "llvm/IR/NoFolder.h" #include "llvm/IR/Operator.h" #include "gtest/gtest.h" #include <memory> @@ -516,7 +517,8 @@ TEST(InstructionsTest, CloneCall) { { AttrBuilder AB; AB.addAttribute(Attribute::ReadOnly); - Call->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); + Call->setAttributes( + AttributeList::get(C, AttributeList::FunctionIndex, AB)); std::unique_ptr<CallInst> Clone(cast<CallInst>(Call->clone())); EXPECT_TRUE(Clone->onlyReadsMemory()); } @@ -534,7 +536,7 @@ TEST(InstructionsTest, AlterCallBundles) { Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail); AttrBuilder AB; AB.addAttribute(Attribute::Cold); - Call->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); + Call->setAttributes(AttributeList::get(C, AttributeList::FunctionIndex, AB)); Call->setDebugLoc(DebugLoc(MDNode::get(C, None))); OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); @@ -562,7 +564,8 @@ TEST(InstructionsTest, AlterInvokeBundles) { Callee, NormalDest.get(), UnwindDest.get(), Args, OldBundle, "result")); AttrBuilder AB; AB.addAttribute(Attribute::Cold); - Invoke->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB)); + Invoke->setAttributes( + AttributeList::get(C, AttributeList::FunctionIndex, AB)); Invoke->setDebugLoc(DebugLoc(MDNode::get(C, None))); OperandBundleDef NewBundle("after", ConstantInt::get(Int32Ty, 7)); @@ -579,5 +582,163 @@ TEST(InstructionsTest, AlterInvokeBundles) { EXPECT_TRUE(Clone->getOperandBundle("after").hasValue()); } +TEST_F(ModuleWithFunctionTest, DropPoisonGeneratingFlags) { + auto *OnlyBB = BasicBlock::Create(Ctx, "bb", F); + auto *Arg0 = &*F->arg_begin(); + + IRBuilder<NoFolder> B(Ctx); + B.SetInsertPoint(OnlyBB); + + { + auto *UI = + cast<Instruction>(B.CreateUDiv(Arg0, Arg0, "", /*isExact*/ true)); + ASSERT_TRUE(UI->isExact()); + UI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(UI->isExact()); + } + + { + auto *ShrI = + cast<Instruction>(B.CreateLShr(Arg0, Arg0, "", /*isExact*/ true)); + ASSERT_TRUE(ShrI->isExact()); + ShrI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(ShrI->isExact()); + } + + { + auto *AI = cast<Instruction>( + B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ false)); + ASSERT_TRUE(AI->hasNoUnsignedWrap()); + AI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(AI->hasNoUnsignedWrap()); + ASSERT_FALSE(AI->hasNoSignedWrap()); + } + + { + auto *SI = cast<Instruction>( + B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ false, /*HasNSW*/ true)); + ASSERT_TRUE(SI->hasNoSignedWrap()); + SI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(SI->hasNoUnsignedWrap()); + ASSERT_FALSE(SI->hasNoSignedWrap()); + } + + { + auto *ShlI = cast<Instruction>( + B.CreateShl(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ true)); + ASSERT_TRUE(ShlI->hasNoSignedWrap()); + ASSERT_TRUE(ShlI->hasNoUnsignedWrap()); + ShlI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(ShlI->hasNoUnsignedWrap()); + ASSERT_FALSE(ShlI->hasNoSignedWrap()); + } + + { + Value *GEPBase = Constant::getNullValue(B.getInt8PtrTy()); + auto *GI = cast<GetElementPtrInst>(B.CreateInBoundsGEP(GEPBase, {Arg0})); + ASSERT_TRUE(GI->isInBounds()); + GI->dropPoisonGeneratingFlags(); + ASSERT_FALSE(GI->isInBounds()); + } +} + +TEST(InstructionsTest, GEPIndices) { + LLVMContext Context; + IRBuilder<NoFolder> Builder(Context); + Type *ElementTy = Builder.getInt8Ty(); + Type *ArrTy = ArrayType::get(ArrayType::get(ElementTy, 64), 64); + Value *Indices[] = { + Builder.getInt32(0), + Builder.getInt32(13), + Builder.getInt32(42) }; + + Value *V = Builder.CreateGEP(ArrTy, UndefValue::get(PointerType::getUnqual(ArrTy)), + Indices); + ASSERT_TRUE(isa<GetElementPtrInst>(V)); + + auto *GEPI = cast<GetElementPtrInst>(V); + ASSERT_NE(GEPI->idx_begin(), GEPI->idx_end()); + ASSERT_EQ(GEPI->idx_end(), std::next(GEPI->idx_begin(), 3)); + EXPECT_EQ(Indices[0], GEPI->idx_begin()[0]); + EXPECT_EQ(Indices[1], GEPI->idx_begin()[1]); + EXPECT_EQ(Indices[2], GEPI->idx_begin()[2]); + EXPECT_EQ(GEPI->idx_begin(), GEPI->indices().begin()); + EXPECT_EQ(GEPI->idx_end(), GEPI->indices().end()); + + const auto *CGEPI = GEPI; + ASSERT_NE(CGEPI->idx_begin(), CGEPI->idx_end()); + ASSERT_EQ(CGEPI->idx_end(), std::next(CGEPI->idx_begin(), 3)); + EXPECT_EQ(Indices[0], CGEPI->idx_begin()[0]); + EXPECT_EQ(Indices[1], CGEPI->idx_begin()[1]); + EXPECT_EQ(Indices[2], CGEPI->idx_begin()[2]); + EXPECT_EQ(CGEPI->idx_begin(), CGEPI->indices().begin()); + EXPECT_EQ(CGEPI->idx_end(), CGEPI->indices().end()); + + delete GEPI; +} + +TEST(InstructionsTest, SwitchInst) { + LLVMContext C; + + std::unique_ptr<BasicBlock> BB1, BB2, BB3; + BB1.reset(BasicBlock::Create(C)); + BB2.reset(BasicBlock::Create(C)); + BB3.reset(BasicBlock::Create(C)); + + // We create block 0 after the others so that it gets destroyed first and + // clears the uses of the other basic blocks. + std::unique_ptr<BasicBlock> BB0(BasicBlock::Create(C)); + + auto *Int32Ty = Type::getInt32Ty(C); + + SwitchInst *SI = + SwitchInst::Create(UndefValue::get(Int32Ty), BB0.get(), 3, BB0.get()); + SI->addCase(ConstantInt::get(Int32Ty, 1), BB1.get()); + SI->addCase(ConstantInt::get(Int32Ty, 2), BB2.get()); + SI->addCase(ConstantInt::get(Int32Ty, 3), BB3.get()); + + auto CI = SI->case_begin(); + ASSERT_NE(CI, SI->case_end()); + EXPECT_EQ(1, CI->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB1.get(), CI->getCaseSuccessor()); + EXPECT_EQ(2, (CI + 1)->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB2.get(), (CI + 1)->getCaseSuccessor()); + EXPECT_EQ(3, (CI + 2)->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB3.get(), (CI + 2)->getCaseSuccessor()); + EXPECT_EQ(CI + 1, std::next(CI)); + EXPECT_EQ(CI + 2, std::next(CI, 2)); + EXPECT_EQ(CI + 3, std::next(CI, 3)); + EXPECT_EQ(SI->case_end(), CI + 3); + EXPECT_EQ(0, CI - CI); + EXPECT_EQ(1, (CI + 1) - CI); + EXPECT_EQ(2, (CI + 2) - CI); + EXPECT_EQ(3, SI->case_end() - CI); + EXPECT_EQ(3, std::distance(CI, SI->case_end())); + + auto CCI = const_cast<const SwitchInst *>(SI)->case_begin(); + SwitchInst::ConstCaseIt CCE = SI->case_end(); + ASSERT_NE(CCI, SI->case_end()); + EXPECT_EQ(1, CCI->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB1.get(), CCI->getCaseSuccessor()); + EXPECT_EQ(2, (CCI + 1)->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB2.get(), (CCI + 1)->getCaseSuccessor()); + EXPECT_EQ(3, (CCI + 2)->getCaseValue()->getSExtValue()); + EXPECT_EQ(BB3.get(), (CCI + 2)->getCaseSuccessor()); + EXPECT_EQ(CCI + 1, std::next(CCI)); + EXPECT_EQ(CCI + 2, std::next(CCI, 2)); + EXPECT_EQ(CCI + 3, std::next(CCI, 3)); + EXPECT_EQ(CCE, CCI + 3); + EXPECT_EQ(0, CCI - CCI); + EXPECT_EQ(1, (CCI + 1) - CCI); + EXPECT_EQ(2, (CCI + 2) - CCI); + EXPECT_EQ(3, CCE - CCI); + EXPECT_EQ(3, std::distance(CCI, CCE)); + + // Make sure that the const iterator is compatible with a const auto ref. + const auto &Handle = *CCI; + EXPECT_EQ(1, Handle.getCaseValue()->getSExtValue()); + EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor()); +} + } // end anonymous namespace } // end namespace llvm diff --git a/unittests/IR/LegacyPassManagerTest.cpp b/unittests/IR/LegacyPassManagerTest.cpp index 9dceb976c9375..0f67d3fb5ac9e 100644 --- a/unittests/IR/LegacyPassManagerTest.cpp +++ b/unittests/IR/LegacyPassManagerTest.cpp @@ -429,7 +429,7 @@ namespace llvm { /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"test1", mod); func_test1->setCallingConv(CallingConv::C); - AttributeSet func_test1_PAL; + AttributeList func_test1_PAL; func_test1->setAttributes(func_test1_PAL); Function* func_test2 = Function::Create( @@ -437,7 +437,7 @@ namespace llvm { /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"test2", mod); func_test2->setCallingConv(CallingConv::C); - AttributeSet func_test2_PAL; + AttributeList func_test2_PAL; func_test2->setAttributes(func_test2_PAL); Function* func_test3 = Function::Create( @@ -445,7 +445,7 @@ namespace llvm { /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"test3", mod); func_test3->setCallingConv(CallingConv::C); - AttributeSet func_test3_PAL; + AttributeList func_test3_PAL; func_test3->setAttributes(func_test3_PAL); Function* func_test4 = Function::Create( @@ -453,7 +453,7 @@ namespace llvm { /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"test4", mod); func_test4->setCallingConv(CallingConv::C); - AttributeSet func_test4_PAL; + AttributeList func_test4_PAL; func_test4->setAttributes(func_test4_PAL); // Global Variable Declarations @@ -474,7 +474,8 @@ namespace llvm { // Block entry (label_entry) CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry); int32_3->setCallingConv(CallingConv::C); - int32_3->setTailCall(false);AttributeSet int32_3_PAL; + int32_3->setTailCall(false); + AttributeList int32_3_PAL; int32_3->setAttributes(int32_3_PAL); ReturnInst::Create(Context, int32_3, label_entry); @@ -489,7 +490,8 @@ namespace llvm { // Block entry (label_entry_5) CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5); int32_6->setCallingConv(CallingConv::C); - int32_6->setTailCall(false);AttributeSet int32_6_PAL; + int32_6->setTailCall(false); + AttributeList int32_6_PAL; int32_6->setAttributes(int32_6_PAL); ReturnInst::Create(Context, int32_6, label_entry_5); @@ -504,7 +506,8 @@ namespace llvm { // Block entry (label_entry_8) CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8); int32_9->setCallingConv(CallingConv::C); - int32_9->setTailCall(false);AttributeSet int32_9_PAL; + int32_9->setTailCall(false); + AttributeList int32_9_PAL; int32_9->setAttributes(int32_9_PAL); ReturnInst::Create(Context, int32_9, label_entry_8); diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 7bb8d4010d38a..103ba4c92ddf1 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -95,7 +95,7 @@ protected: return DICompileUnit::getDistinct(Context, 1, getFile(), "clang", false, "-g", 2, "", DICompileUnit::FullDebug, getTuple(), getTuple(), getTuple(), - getTuple(), getTuple(), 0, true); + getTuple(), getTuple(), 0, true, false); } DIType *getBasicType(StringRef Name) { return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); @@ -103,7 +103,7 @@ protected: DIType *getDerivedType() { return DIDerivedType::getDistinct( Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, - getBasicType("basictype"), 1, 2, 0, DINode::FlagZero); + getBasicType("basictype"), 1, 2, 0, None, DINode::FlagZero); } Constant *getConstant() { return ConstantInt::get(Type::getInt32Ty(Context), Counter++); @@ -1053,12 +1053,14 @@ TEST_F(DIDerivedTypeTest, get) { DIScope *Scope = getSubprogram(); DIType *BaseType = getBasicType("basic"); MDTuple *ExtraData = getTuple(); + unsigned DWARFAddressSpace = 8; DINode::DIFlags Flags5 = static_cast<DINode::DIFlags>(5); DINode::DIFlags Flags4 = static_cast<DINode::DIFlags>(4); auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, - 1, Scope, BaseType, 2, 3, 4, Flags5, ExtraData); + 1, Scope, BaseType, 2, 3, 4, DWARFAddressSpace, Flags5, + ExtraData); EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag()); EXPECT_EQ("something", N->getName()); EXPECT_EQ(File, N->getFile()); @@ -1068,45 +1070,51 @@ TEST_F(DIDerivedTypeTest, get) { EXPECT_EQ(2u, N->getSizeInBits()); EXPECT_EQ(3u, N->getAlignInBits()); EXPECT_EQ(4u, N->getOffsetInBits()); + EXPECT_EQ(DWARFAddressSpace, N->getDWARFAddressSpace().getValue()); EXPECT_EQ(5u, N->getFlags()); EXPECT_EQ(ExtraData, N->getExtraData()); EXPECT_EQ(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, Flags5, ExtraData)); + 4, DWARFAddressSpace, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, Flags5, ExtraData)); + 4, DWARFAddressSpace, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else", - File, 1, Scope, BaseType, 2, 3, 4, Flags5, - ExtraData)); + File, 1, Scope, BaseType, 2, 3, + 4, DWARFAddressSpace, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", getFile(), 1, Scope, BaseType, 2, - 3, 4, Flags5, ExtraData)); + 3, 4, DWARFAddressSpace, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 2, Scope, BaseType, 2, 3, - 4, Flags5, ExtraData)); + 4, DWARFAddressSpace, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, getSubprogram(), - BaseType, 2, 3, 4, Flags5, ExtraData)); + BaseType, 2, 3, 4, DWARFAddressSpace, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get( Context, dwarf::DW_TAG_pointer_type, "something", File, 1, - Scope, getBasicType("basic2"), 2, 3, 4, Flags5, ExtraData)); + Scope, getBasicType("basic2"), 2, 3, 4, DWARFAddressSpace, + Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 3, 3, - 4, Flags5, ExtraData)); + 4, DWARFAddressSpace, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 2, - 4, Flags5, ExtraData)); + 4, DWARFAddressSpace, Flags5, ExtraData)); + EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, + "something", File, 1, Scope, BaseType, 2, 3, + 5, DWARFAddressSpace, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 5, Flags5, ExtraData)); + 4, DWARFAddressSpace + 1, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, Flags4, ExtraData)); + 4, DWARFAddressSpace, Flags4, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, Flags5, getTuple())); + 4, DWARFAddressSpace, Flags5, getTuple())); TempDIDerivedType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -1121,10 +1129,12 @@ TEST_F(DIDerivedTypeTest, getWithLargeValues) { auto *N = DIDerivedType::get( Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, - BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, Flags, ExtraData); + BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, + Flags, ExtraData); EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits()); + EXPECT_EQ(UINT32_MAX - 3, N->getDWARFAddressSpace().getValue()); } typedef MetadataTest DICompositeTypeTest; @@ -1406,7 +1416,8 @@ TEST_F(DICompileUnitTest, get) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true); + RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true, + false); EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); EXPECT_EQ(SourceLanguage, N->getSourceLanguage()); @@ -1463,7 +1474,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true); + RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true, false); auto *GlobalVariables = MDTuple::getDistinct(Context, None); EXPECT_EQ(nullptr, N->getGlobalVariables().get()); diff --git a/unittests/IR/ValueHandleTest.cpp b/unittests/IR/ValueHandleTest.cpp index 59cd9d7ba37ae..1abc87c2fdc7f 100644 --- a/unittests/IR/ValueHandleTest.cpp +++ b/unittests/IR/ValueHandleTest.cpp @@ -412,4 +412,97 @@ TEST_F(ValueHandle, AssertingVHCheckedLast) { BitcastV.reset(); } +TEST_F(ValueHandle, PoisoningVH_BasicOperation) { + PoisoningVH<CastInst> VH(BitcastV.get()); + CastInst *implicit_to_exact_type = VH; + (void)implicit_to_exact_type; // Avoid warning. + + PoisoningVH<Value> GenericVH(BitcastV.get()); + EXPECT_EQ(BitcastV.get(), GenericVH); + GenericVH = ConstantV; + EXPECT_EQ(ConstantV, GenericVH); + + // Make sure I can call a method on the underlying CastInst. It + // doesn't matter which method. + EXPECT_FALSE(VH->mayWriteToMemory()); + EXPECT_FALSE((*VH).mayWriteToMemory()); +} + +TEST_F(ValueHandle, PoisoningVH_Const) { + const CastInst *ConstBitcast = BitcastV.get(); + PoisoningVH<const CastInst> VH(ConstBitcast); + const CastInst *implicit_to_exact_type = VH; + (void)implicit_to_exact_type; // Avoid warning. +} + +TEST_F(ValueHandle, PoisoningVH_Comparisons) { + PoisoningVH<Value> BitcastVH(BitcastV.get()); + PoisoningVH<Value> ConstantVH(ConstantV); + + EXPECT_TRUE(BitcastVH == BitcastVH); + EXPECT_TRUE(BitcastV.get() == BitcastVH); + EXPECT_TRUE(BitcastVH == BitcastV.get()); + EXPECT_FALSE(BitcastVH == ConstantVH); + + EXPECT_TRUE(BitcastVH != ConstantVH); + EXPECT_TRUE(BitcastV.get() != ConstantVH); + EXPECT_TRUE(BitcastVH != ConstantV); + EXPECT_FALSE(BitcastVH != BitcastVH); + + // Cast to Value* so comparisons work. + Value *BV = BitcastV.get(); + Value *CV = ConstantV; + EXPECT_EQ(BV < CV, BitcastVH < ConstantVH); + EXPECT_EQ(BV <= CV, BitcastVH <= ConstantVH); + EXPECT_EQ(BV > CV, BitcastVH > ConstantVH); + EXPECT_EQ(BV >= CV, BitcastVH >= ConstantVH); + + EXPECT_EQ(BV < CV, BitcastV.get() < ConstantVH); + EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantVH); + EXPECT_EQ(BV > CV, BitcastV.get() > ConstantVH); + EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantVH); + + EXPECT_EQ(BV < CV, BitcastVH < ConstantV); + EXPECT_EQ(BV <= CV, BitcastVH <= ConstantV); + EXPECT_EQ(BV > CV, BitcastVH > ConstantV); + EXPECT_EQ(BV >= CV, BitcastVH >= ConstantV); +} + +TEST_F(ValueHandle, PoisoningVH_DoesNotFollowRAUW) { + PoisoningVH<Value> VH(BitcastV.get()); + BitcastV->replaceAllUsesWith(ConstantV); + EXPECT_TRUE(DenseMapInfo<PoisoningVH<Value>>::isEqual(VH, BitcastV.get())); +} + +#ifdef NDEBUG + +TEST_F(ValueHandle, PoisoningVH_ReducesToPointer) { + EXPECT_EQ(sizeof(CastInst *), sizeof(PoisoningVH<CastInst>)); +} + +#else // !NDEBUG + +#ifdef GTEST_HAS_DEATH_TEST + +TEST_F(ValueHandle, PoisoningVH_Asserts) { + PoisoningVH<Value> VH(BitcastV.get()); + + // The poisoned handle shouldn't assert when the value is deleted. + BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context))); + // But should when we access the handle. + EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!"); + + // Now check that poison catches RAUW. + VH = BitcastV.get(); + // The replace doesn't trigger anything immediately. + BitcastV->replaceAllUsesWith(ConstantV); + // But a use does. + EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!"); + + // Don't clear anything out here as destroying the handles should be fine. +} + +#endif // GTEST_HAS_DEATH_TEST + +#endif // NDEBUG } diff --git a/unittests/IR/ValueTest.cpp b/unittests/IR/ValueTest.cpp index 607b7a1bd2c9b..142444a809c6d 100644 --- a/unittests/IR/ValueTest.cpp +++ b/unittests/IR/ValueTest.cpp @@ -40,7 +40,7 @@ TEST(ValueTest, UsedInBasicBlock) { Function *F = M->getFunction("f"); EXPECT_FALSE(F->isUsedInBasicBlock(&F->front())); - EXPECT_TRUE((++F->arg_begin())->isUsedInBasicBlock(&F->front())); + EXPECT_TRUE(std::next(F->arg_begin())->isUsedInBasicBlock(&F->front())); EXPECT_TRUE(F->arg_begin()->isUsedInBasicBlock(&F->front())); } diff --git a/unittests/IR/VerifierTest.cpp b/unittests/IR/VerifierTest.cpp index ad6940afd05ef..188509aadf77a 100644 --- a/unittests/IR/VerifierTest.cpp +++ b/unittests/IR/VerifierTest.cpp @@ -52,9 +52,9 @@ TEST(VerifierTest, InvalidRetAttribute) { Module M("M", C); FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false); Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy)); - AttributeSet AS = F->getAttributes(); - F->setAttributes(AS.addAttribute(C, AttributeSet::ReturnIndex, - Attribute::UWTable)); + AttributeList AS = F->getAttributes(); + F->setAttributes( + AS.addAttribute(C, AttributeList::ReturnIndex, Attribute::UWTable)); std::string Error; raw_string_ostream ErrorOS(Error); |