summaryrefslogtreecommitdiff
path: root/unittests/IR
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/IR')
-rw-r--r--unittests/IR/AttributesTest.cpp20
-rw-r--r--unittests/IR/FunctionTest.cpp21
-rw-r--r--unittests/IR/IRBuilderTest.cpp22
-rw-r--r--unittests/IR/InstructionsTest.cpp167
-rw-r--r--unittests/IR/LegacyPassManagerTest.cpp17
-rw-r--r--unittests/IR/MetadataTest.cpp49
-rw-r--r--unittests/IR/ValueHandleTest.cpp93
-rw-r--r--unittests/IR/ValueTest.cpp2
-rw-r--r--unittests/IR/VerifierTest.cpp6
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);