summaryrefslogtreecommitdiff
path: root/unittests
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-11-24 09:08:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-11-24 09:08:18 +0000
commit5ca98fd98791947eba83a1ed3f2c8191ef7afa6c (patch)
treef5944309621cee4fe0976be6f9ac619b7ebfc4c2 /unittests
parent68bcb7db193e4bc81430063148253d30a791023e (diff)
Notes
Diffstat (limited to 'unittests')
-rw-r--r--unittests/ADT/APFloatTest.cpp54
-rw-r--r--unittests/ADT/APIntTest.cpp81
-rw-r--r--unittests/ADT/APSIntTest.cpp44
-rw-r--r--unittests/ADT/ArrayRefTest.cpp40
-rw-r--r--unittests/ADT/BitVectorTest.cpp6
-rw-r--r--unittests/ADT/CMakeLists.txt14
-rw-r--r--unittests/ADT/DenseMapTest.cpp36
-rw-r--r--unittests/ADT/DenseSetTest.cpp2
-rw-r--r--unittests/ADT/HashingTest.cpp4
-rw-r--r--unittests/ADT/ImmutableMapTest.cpp4
-rw-r--r--unittests/ADT/MakeUniqueTest.cpp76
-rw-r--r--unittests/ADT/MapVectorTest.cpp36
-rw-r--r--unittests/ADT/OptionalTest.cpp2
-rw-r--r--unittests/ADT/PointerIntPairTest.cpp76
-rw-r--r--unittests/ADT/PointerUnionTest.cpp44
-rw-r--r--unittests/ADT/SCCIteratorTest.cpp4
-rw-r--r--unittests/ADT/SmallPtrSetTest.cpp87
-rw-r--r--unittests/ADT/SmallVectorTest.cpp273
-rw-r--r--unittests/ADT/StringMapTest.cpp162
-rw-r--r--unittests/ADT/StringRefTest.cpp18
-rw-r--r--unittests/ADT/TinyPtrVectorTest.cpp118
-rw-r--r--unittests/ADT/TripleTest.cpp105
-rw-r--r--unittests/ADT/ilistTest.cpp10
-rw-r--r--unittests/ADT/polymorphic_ptr_test.cpp129
-rw-r--r--unittests/Analysis/CFGTest.cpp97
-rw-r--r--unittests/Analysis/CMakeLists.txt4
-rw-r--r--unittests/Analysis/LazyCallGraphTest.cpp720
-rw-r--r--unittests/Analysis/MixedTBAATest.cpp77
-rw-r--r--unittests/Analysis/ScalarEvolutionTest.cpp4
-rw-r--r--unittests/Bitcode/BitReaderTest.cpp10
-rw-r--r--unittests/Bitcode/CMakeLists.txt2
-rw-r--r--unittests/CMakeLists.txt9
-rw-r--r--unittests/CodeGen/CMakeLists.txt5
-rw-r--r--unittests/CodeGen/DIEHashTest.cpp297
-rw-r--r--unittests/DebugInfo/CMakeLists.txt4
-rw-r--r--unittests/ExecutionEngine/CMakeLists.txt13
-rw-r--r--unittests/ExecutionEngine/ExecutionEngineTest.cpp25
-rw-r--r--unittests/ExecutionEngine/JIT/CMakeLists.txt15
-rw-r--r--unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp2
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp7
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h8
-rw-r--r--unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp45
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp62
-rw-r--r--unittests/ExecutionEngine/JIT/Makefile3
-rw-r--r--unittests/ExecutionEngine/JIT/MultiJITTest.cpp51
-rw-r--r--unittests/ExecutionEngine/MCJIT/CMakeLists.txt14
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp278
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp33
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp86
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp41
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTest.cpp12
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h10
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestBase.h43
-rw-r--r--unittests/ExecutionEngine/MCJIT/Makefile2
-rw-r--r--unittests/IR/CMakeLists.txt18
-rw-r--r--unittests/IR/ConstantRangeTest.cpp (renamed from unittests/Support/ConstantRangeTest.cpp)12
-rw-r--r--unittests/IR/ConstantsTest.cpp20
-rw-r--r--unittests/IR/DominatorTreeTest.cpp42
-rw-r--r--unittests/IR/IRBuilderTest.cpp77
-rw-r--r--unittests/IR/InstructionsTest.cpp128
-rw-r--r--unittests/IR/LeakDetectorTest.cpp (renamed from unittests/Support/LeakDetectorTest.cpp)4
-rw-r--r--unittests/IR/LegacyPassManagerTest.cpp44
-rw-r--r--unittests/IR/MDBuilderTest.cpp15
-rw-r--r--unittests/IR/MetadataTest.cpp4
-rw-r--r--unittests/IR/PassManagerTest.cpp277
-rw-r--r--unittests/IR/PatternMatch.cpp373
-rw-r--r--unittests/IR/TypeBuilderTest.cpp6
-rw-r--r--unittests/IR/UserTest.cpp96
-rw-r--r--unittests/IR/ValueHandleTest.cpp (renamed from unittests/Support/ValueHandleTest.cpp)39
-rw-r--r--unittests/IR/ValueMapTest.cpp48
-rw-r--r--unittests/IR/ValueTest.cpp10
-rw-r--r--unittests/IR/VerifierTest.cpp29
-rw-r--r--unittests/IR/WaymarkTest.cpp2
-rw-r--r--unittests/LineEditor/CMakeLists.txt7
-rw-r--r--unittests/LineEditor/LineEditor.cpp83
-rw-r--r--unittests/LineEditor/Makefile15
-rw-r--r--unittests/Linker/CMakeLists.txt12
-rw-r--r--unittests/Linker/LinkModulesTest.cpp156
-rw-r--r--unittests/Linker/Makefile (renamed from unittests/Object/Makefile)6
-rw-r--r--unittests/MC/CMakeLists.txt10
-rw-r--r--unittests/MC/MCAtomTest.cpp4
-rw-r--r--unittests/MC/Makefile2
-rw-r--r--unittests/MC/StringTableBuilderTest.cpp40
-rw-r--r--unittests/MC/YAMLTest.cpp (renamed from unittests/Object/YAMLTest.cpp)6
-rw-r--r--unittests/Makefile5
-rw-r--r--unittests/Makefile.unittest21
-rw-r--r--unittests/Object/CMakeLists.txt7
-rw-r--r--unittests/Option/CMakeLists.txt2
-rw-r--r--unittests/Option/OptionParsingTest.cpp30
-rw-r--r--unittests/Support/AllocatorTest.cpp68
-rw-r--r--unittests/Support/BlockFrequencyTest.cpp151
-rw-r--r--unittests/Support/BranchProbabilityTest.cpp282
-rw-r--r--unittests/Support/CMakeLists.txt13
-rw-r--r--unittests/Support/Casting.cpp22
-rw-r--r--unittests/Support/CommandLineTest.cpp80
-rw-r--r--unittests/Support/CompressionTest.cpp18
-rw-r--r--unittests/Support/ConvertUTFTest.cpp1599
-rw-r--r--unittests/Support/DataExtractorTest.cpp2
-rw-r--r--unittests/Support/ErrorOrTest.cpp26
-rw-r--r--unittests/Support/FileOutputBufferTest.cpp43
-rw-r--r--unittests/Support/IteratorTest.cpp101
-rw-r--r--unittests/Support/LEB128Test.cpp311
-rw-r--r--unittests/Support/LineIteratorTest.cpp115
-rw-r--r--unittests/Support/LockFileManagerTest.cpp87
-rw-r--r--unittests/Support/ManagedStatic.cpp12
-rw-r--r--unittests/Support/MemoryBufferTest.cpp43
-rw-r--r--unittests/Support/MemoryTest.cpp174
-rw-r--r--unittests/Support/Path.cpp206
-rw-r--r--unittests/Support/ProcessTest.cpp9
-rw-r--r--unittests/Support/ProgramTest.cpp61
-rw-r--r--unittests/Support/RegexTest.cpp30
-rw-r--r--unittests/Support/ScaledNumberTest.cpp536
-rw-r--r--unittests/Support/SpecialCaseListTest.cpp126
-rw-r--r--unittests/Support/StringPool.cpp31
-rw-r--r--unittests/Support/SwapByteOrderTest.cpp158
-rw-r--r--unittests/Support/ThreadLocalTest.cpp4
-rw-r--r--unittests/Support/TimeValueTest.cpp7
-rw-r--r--unittests/Support/YAMLIOTest.cpp259
-rw-r--r--unittests/Support/raw_ostream_test.cpp4
-rw-r--r--unittests/Transforms/DebugIR/CMakeLists.txt2
-rw-r--r--unittests/Transforms/DebugIR/DebugIR.cpp25
-rw-r--r--unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp102
-rw-r--r--unittests/Transforms/Utils/CMakeLists.txt4
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp237
-rw-r--r--unittests/Transforms/Utils/IntegerDivision.cpp122
-rw-r--r--unittests/Transforms/Utils/SpecialCaseList.cpp232
126 files changed, 8416 insertions, 1940 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index e57c8d4b931f..8f298cdfedb3 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -1173,11 +1173,11 @@ TEST(APFloatTest, exactInverse) {
EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
// Large float, inverse is a denormal.
- EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(0));
+ EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(nullptr));
// Zero
- EXPECT_FALSE(APFloat(0.0).getExactInverse(0));
+ EXPECT_FALSE(APFloat(0.0).getExactInverse(nullptr));
// Denormalized float
- EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0));
+ EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(nullptr));
}
TEST(APFloatTest, roundToIntegral) {
@@ -1844,10 +1844,10 @@ TEST(APFloatTest, subtract) {
{ PInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
{ PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
- { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { PInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
{ PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
@@ -1861,10 +1861,10 @@ TEST(APFloatTest, subtract) {
{ MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
{ MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
{ MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
- { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { MInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
{ MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
@@ -1878,10 +1878,10 @@ TEST(APFloatTest, subtract) {
{ PZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
{ PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
- { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { PZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ PZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
{ PZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
@@ -1895,10 +1895,10 @@ TEST(APFloatTest, subtract) {
{ MZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
{ MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
- { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { MZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ MZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
{ MZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
@@ -1946,10 +1946,10 @@ TEST(APFloatTest, subtract) {
{ PNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
{ PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
- { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { PNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ PNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
{ PNormalValue, MNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
@@ -1963,10 +1963,10 @@ TEST(APFloatTest, subtract) {
{ MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
{ MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
- { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { MNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ MNormalValue, PNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
{ MNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
@@ -1980,10 +1980,10 @@ TEST(APFloatTest, subtract) {
{ PLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
{ PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
- { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { PLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
{ PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
@@ -1997,10 +1997,10 @@ TEST(APFloatTest, subtract) {
{ MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
{ MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
- { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { MLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
{ MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
@@ -2014,10 +2014,10 @@ TEST(APFloatTest, subtract) {
{ PSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
{ PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
- { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { PSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ PSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
{ PSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
@@ -2031,10 +2031,10 @@ TEST(APFloatTest, subtract) {
{ MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
{ MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
- { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { MSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ MSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
{ MSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
@@ -2048,10 +2048,10 @@ TEST(APFloatTest, subtract) {
{ PSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
{ PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
- { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { PSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { PSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ PSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
{ PSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
@@ -2065,10 +2065,10 @@ TEST(APFloatTest, subtract) {
{ MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
{ MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
{ MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
- { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
+ { MSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
#if 0
// See Note 1.
- { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
+ { MSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
#endif
{ MSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
{ MSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index 3c0dfe144044..19c47ab13bf9 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -597,4 +597,85 @@ TEST(APIntTest, tcDecrement) {
EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
}
}
+
+TEST(APIntTest, arrayAccess) {
+ // Single word check.
+ uint64_t E1 = 0x2CA7F46BF6569915ULL;
+ APInt A1(64, E1);
+ for (unsigned i = 0, e = 64; i < e; ++i) {
+ EXPECT_EQ(bool(E1 & (1ULL << i)),
+ A1[i]);
+ }
+
+ // Multiword check.
+ integerPart E2[4] = {
+ 0xEB6EB136591CBA21ULL,
+ 0x7B9358BD6A33F10AULL,
+ 0x7E7FFA5EADD8846ULL,
+ 0x305F341CA00B613DULL
+ };
+ APInt A2(integerPartWidth*4, ArrayRef<integerPart>(E2, 4));
+ for (unsigned i = 0; i < 4; ++i) {
+ for (unsigned j = 0; j < integerPartWidth; ++j) {
+ EXPECT_EQ(bool(E2[i] & (1ULL << j)),
+ A2[i*integerPartWidth + j]);
+ }
+ }
+}
+
+TEST(APIntTest, LargeAPIntConstruction) {
+ // Check that we can properly construct very large APInt. It is very
+ // unlikely that people will ever do this, but it is a legal input,
+ // so we should not crash on it.
+ APInt A9(UINT32_MAX, 0);
+ EXPECT_FALSE(A9.getBoolValue());
+}
+
+TEST(APIntTest, nearestLogBase2) {
+ // Single word check.
+
+ // Test round up.
+ uint64_t I1 = 0x1800001;
+ APInt A1(64, I1);
+ EXPECT_EQ(A1.nearestLogBase2(), A1.ceilLogBase2());
+
+ // Test round down.
+ uint64_t I2 = 0x1000011;
+ APInt A2(64, I2);
+ EXPECT_EQ(A2.nearestLogBase2(), A2.logBase2());
+
+ // Test ties round up.
+ uint64_t I3 = 0x1800000;
+ APInt A3(64, I3);
+ EXPECT_EQ(A3.nearestLogBase2(), A3.ceilLogBase2());
+
+ // Multiple word check.
+
+ // Test round up.
+ integerPart I4[4] = {0x0, 0xF, 0x18, 0x0};
+ APInt A4(integerPartWidth*4, ArrayRef<integerPart>(I4, 4));
+ EXPECT_EQ(A4.nearestLogBase2(), A4.ceilLogBase2());
+
+ // Test round down.
+ integerPart I5[4] = {0x0, 0xF, 0x10, 0x0};
+ APInt A5(integerPartWidth*4, ArrayRef<integerPart>(I5, 4));
+ EXPECT_EQ(A5.nearestLogBase2(), A5.logBase2());
+
+ // Test ties round up.
+ uint64_t I6[4] = {0x0, 0x0, 0x0, 0x18};
+ APInt A6(integerPartWidth*4, ArrayRef<integerPart>(I6, 4));
+ EXPECT_EQ(A6.nearestLogBase2(), A6.ceilLogBase2());
+
+ // Test BitWidth == 1 special cases.
+ APInt A7(1, 1);
+ EXPECT_EQ(A7.nearestLogBase2(), 0ULL);
+ APInt A8(1, 0);
+ EXPECT_EQ(A8.nearestLogBase2(), UINT32_MAX);
+
+ // Test the zero case when we have a bit width large enough such
+ // that the bit width is larger than UINT32_MAX-1.
+ APInt A9(UINT32_MAX, 0);
+ EXPECT_EQ(A9.nearestLogBase2(), UINT32_MAX);
+}
+
}
diff --git a/unittests/ADT/APSIntTest.cpp b/unittests/ADT/APSIntTest.cpp
new file mode 100644
index 000000000000..eef9c8a90af9
--- /dev/null
+++ b/unittests/ADT/APSIntTest.cpp
@@ -0,0 +1,44 @@
+//===- llvm/unittest/ADT/APSIntTest.cpp - APSInt unit tests ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/APSInt.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(APSIntTest, MoveTest) {
+ APSInt A(32, true);
+ EXPECT_TRUE(A.isUnsigned());
+
+ APSInt B(128, false);
+ A = B;
+ EXPECT_FALSE(A.isUnsigned());
+
+ APSInt C(B);
+ EXPECT_FALSE(C.isUnsigned());
+
+ APInt Wide(256, 0);
+ const uint64_t *Bits = Wide.getRawData();
+ APSInt D(std::move(Wide));
+ EXPECT_TRUE(D.isUnsigned());
+ EXPECT_EQ(Bits, D.getRawData()); // Verify that "Wide" was really moved.
+
+ A = APSInt(64, true);
+ EXPECT_TRUE(A.isUnsigned());
+
+ Wide = APInt(128, 1);
+ Bits = Wide.getRawData();
+ A = std::move(Wide);
+ EXPECT_TRUE(A.isUnsigned());
+ EXPECT_EQ(Bits, A.getRawData()); // Verify that "Wide" was really moved.
+}
+
+}
diff --git a/unittests/ADT/ArrayRefTest.cpp b/unittests/ADT/ArrayRefTest.cpp
new file mode 100644
index 000000000000..293afc6ea37d
--- /dev/null
+++ b/unittests/ADT/ArrayRefTest.cpp
@@ -0,0 +1,40 @@
+//===- llvm/unittest/ADT/ArrayRefTest.cpp - ArrayRef unit tests -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace llvm {
+
+TEST(ArrayRefTest, AllocatorCopy) {
+ BumpPtrAllocator Alloc;
+ static const uint16_t Words1[] = { 1, 4, 200, 37 };
+ ArrayRef<uint16_t> Array1 = makeArrayRef(Words1, 4);
+ static const uint16_t Words2[] = { 11, 4003, 67, 64000, 13 };
+ ArrayRef<uint16_t> Array2 = makeArrayRef(Words2, 5);
+ ArrayRef<uint16_t> Array1c = Array1.copy(Alloc);
+ ArrayRef<uint16_t> Array2c = Array2.copy(Alloc);;
+ EXPECT_TRUE(Array1.equals(Array1c));
+ EXPECT_NE(Array1.data(), Array1c.data());
+ EXPECT_TRUE(Array2.equals(Array2c));
+ EXPECT_NE(Array2.data(), Array2c.data());
+}
+
+TEST(ArrayRefTest, DropBack) {
+ static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};
+ ArrayRef<int> AR1(TheNumbers);
+ ArrayRef<int> AR2(TheNumbers, AR1.size() - 1);
+ EXPECT_TRUE(AR1.drop_back().equals(AR2));
+}
+
+
+} // end anonymous namespace
diff --git a/unittests/ADT/BitVectorTest.cpp b/unittests/ADT/BitVectorTest.cpp
index d7cde891fb56..3deaff0fe356 100644
--- a/unittests/ADT/BitVectorTest.cpp
+++ b/unittests/ADT/BitVectorTest.cpp
@@ -356,6 +356,12 @@ TYPED_TEST(BitVectorTest, RangeOps) {
EXPECT_TRUE( E.test(1));
EXPECT_TRUE( E.test(32));
EXPECT_FALSE(E.test(33));
+
+ TypeParam BufferOverrun;
+ unsigned size = sizeof(unsigned long) * 8;
+ BufferOverrun.resize(size);
+ BufferOverrun.reset(0, size);
+ BufferOverrun.set(0, size);
}
TYPED_TEST(BitVectorTest, CompoundTestReset) {
diff --git a/unittests/ADT/CMakeLists.txt b/unittests/ADT/CMakeLists.txt
index 8ad303a9e1b3..0f214f3d0c80 100644
--- a/unittests/ADT/CMakeLists.txt
+++ b/unittests/ADT/CMakeLists.txt
@@ -5,6 +5,8 @@ set(LLVM_LINK_COMPONENTS
set(ADTSources
APFloatTest.cpp
APIntTest.cpp
+ APSIntTest.cpp
+ ArrayRefTest.cpp
BitVectorTest.cpp
DAGDeltaAlgorithmTest.cpp
DeltaAlgorithmTest.cpp
@@ -18,9 +20,11 @@ set(ADTSources
IntEqClassesTest.cpp
IntervalMapTest.cpp
IntrusiveRefCntPtrTest.cpp
+ MakeUniqueTest.cpp
MapVectorTest.cpp
OptionalTest.cpp
PackedVectorTest.cpp
+ PointerIntPairTest.cpp
PointerUnionTest.cpp
SCCIteratorTest.cpp
SmallPtrSetTest.cpp
@@ -35,18 +39,8 @@ set(ADTSources
TripleTest.cpp
TwineTest.cpp
VariadicFunctionTest.cpp
- polymorphic_ptr_test.cpp
)
-# They cannot be compiled on MSVC9 due to its bug.
-if(MSVC AND MSVC_VERSION LESS 1600)
- set(LLVM_OPTIONAL_SOURCES
- DenseMapTest.cpp
- SmallVectorTest.cpp
- )
- list(REMOVE_ITEM ADTSources ${LLVM_OPTIONAL_SOURCES})
-endif()
-
add_llvm_unittest(ADTTests
${ADTSources}
)
diff --git a/unittests/ADT/DenseMapTest.cpp b/unittests/ADT/DenseMapTest.cpp
index 15eb6988f669..75a910a24cab 100644
--- a/unittests/ADT/DenseMapTest.cpp
+++ b/unittests/ADT/DenseMapTest.cpp
@@ -92,9 +92,9 @@ protected:
};
template <typename T>
-typename T::key_type *const DenseMapTest<T>::dummy_key_ptr = 0;
+typename T::key_type *const DenseMapTest<T>::dummy_key_ptr = nullptr;
template <typename T>
-typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = 0;
+typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr;
// Register these types for testing.
typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
@@ -119,7 +119,7 @@ TYPED_TEST(DenseMapTest, EmptyIntMapTest) {
// Lookup tests
EXPECT_FALSE(this->Map.count(this->getKey()));
EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end());
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || defined(__clang__)
EXPECT_EQ(typename TypeParam::mapped_type(),
this->Map.lookup(this->getKey()));
#else
@@ -209,6 +209,34 @@ TYPED_TEST(DenseMapTest, CopyConstructorTest) {
EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
}
+// Test copy constructor method where SmallDenseMap isn't small.
+TYPED_TEST(DenseMapTest, CopyConstructorNotSmallTest) {
+ for (int Key = 0; Key < 5; ++Key)
+ this->Map[this->getKey(Key)] = this->getValue(Key);
+ TypeParam copyMap(this->Map);
+
+ EXPECT_EQ(5u, copyMap.size());
+ for (int Key = 0; Key < 5; ++Key)
+ EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
+}
+
+// Test copying from a default-constructed map.
+TYPED_TEST(DenseMapTest, CopyConstructorFromDefaultTest) {
+ TypeParam copyMap(this->Map);
+
+ EXPECT_TRUE(copyMap.empty());
+}
+
+// Test copying from an empty map where SmallDenseMap isn't small.
+TYPED_TEST(DenseMapTest, CopyConstructorFromEmptyTest) {
+ for (int Key = 0; Key < 5; ++Key)
+ this->Map[this->getKey(Key)] = this->getValue(Key);
+ this->Map.clear();
+ TypeParam copyMap(this->Map);
+
+ EXPECT_TRUE(copyMap.empty());
+}
+
// Test assignment operator method
TYPED_TEST(DenseMapTest, AssignmentTest) {
this->Map[this->getKey()] = this->getValue();
@@ -317,7 +345,7 @@ TEST(DenseMapCustomTest, FindAsTest) {
EXPECT_EQ(3u, map.size());
// Normal lookup tests
- EXPECT_EQ(1, map.count(1));
+ EXPECT_EQ(1u, map.count(1));
EXPECT_EQ(1u, map.find(0)->second);
EXPECT_EQ(2u, map.find(1)->second);
EXPECT_EQ(3u, map.find(2)->second);
diff --git a/unittests/ADT/DenseSetTest.cpp b/unittests/ADT/DenseSetTest.cpp
index ada5f6db83af..154c5892d5fd 100644
--- a/unittests/ADT/DenseSetTest.cpp
+++ b/unittests/ADT/DenseSetTest.cpp
@@ -24,7 +24,7 @@ TEST_F(DenseSetTest, DoubleEntrySetTest) {
set.insert(0);
set.insert(1);
// Original failure was an infinite loop in this call:
- EXPECT_EQ(0, set.count(2));
+ EXPECT_EQ(0u, set.count(2));
}
}
diff --git a/unittests/ADT/HashingTest.cpp b/unittests/ADT/HashingTest.cpp
index 1b3d0617a5e3..acaa83cddddd 100644
--- a/unittests/ADT/HashingTest.cpp
+++ b/unittests/ADT/HashingTest.cpp
@@ -41,7 +41,7 @@ struct NonPOD {
namespace hashing {
namespace detail {
-template <> struct is_hashable_data<LargeTestInteger> : true_type {};
+template <> struct is_hashable_data<LargeTestInteger> : std::true_type {};
} // namespace detail
} // namespace hashing
@@ -58,7 +58,7 @@ enum TestEnumeration {
TEST(HashingTest, HashValueBasicTest) {
int x = 42, y = 43, c = 'x';
- void *p = 0;
+ void *p = nullptr;
uint64_t i = 71;
const unsigned ci = 71;
volatile int vi = 71;
diff --git a/unittests/ADT/ImmutableMapTest.cpp b/unittests/ADT/ImmutableMapTest.cpp
index 774581ca4eeb..6a99884bfbb3 100644
--- a/unittests/ADT/ImmutableMapTest.cpp
+++ b/unittests/ADT/ImmutableMapTest.cpp
@@ -36,8 +36,8 @@ TEST(ImmutableMapTest, MultiElemIntMapTest) {
EXPECT_TRUE(S.isEmpty());
EXPECT_FALSE(S2.isEmpty());
- EXPECT_EQ(0, S.lookup(3));
- EXPECT_EQ(0, S.lookup(9));
+ EXPECT_EQ(nullptr, S.lookup(3));
+ EXPECT_EQ(nullptr, S.lookup(9));
EXPECT_EQ(10, *S2.lookup(3));
EXPECT_EQ(11, *S2.lookup(4));
diff --git a/unittests/ADT/MakeUniqueTest.cpp b/unittests/ADT/MakeUniqueTest.cpp
new file mode 100644
index 000000000000..3b4938a2ef36
--- /dev/null
+++ b/unittests/ADT/MakeUniqueTest.cpp
@@ -0,0 +1,76 @@
+//===- llvm/unittest/ADT/MakeUniqueTest.cpp - make_unique unit tests ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "gtest/gtest.h"
+#include <tuple>
+using namespace llvm;
+
+namespace {
+
+TEST(MakeUniqueTest, SingleObject) {
+ auto p0 = make_unique<int>();
+ EXPECT_TRUE((bool)p0);
+ EXPECT_EQ(0, *p0);
+
+ auto p1 = make_unique<int>(5);
+ EXPECT_TRUE((bool)p1);
+ EXPECT_EQ(5, *p1);
+
+ auto p2 = make_unique<std::tuple<int, int>>(0, 1);
+ EXPECT_TRUE((bool)p2);
+ EXPECT_EQ(std::make_tuple(0, 1), *p2);
+
+ auto p3 = make_unique<std::tuple<int, int, int>>(0, 1, 2);
+ EXPECT_TRUE((bool)p3);
+ EXPECT_EQ(std::make_tuple(0, 1, 2), *p3);
+
+ auto p4 = make_unique<std::tuple<int, int, int, int>>(0, 1, 2, 3);
+ EXPECT_TRUE((bool)p4);
+ EXPECT_EQ(std::make_tuple(0, 1, 2, 3), *p4);
+
+ auto p5 = make_unique<std::tuple<int, int, int, int, int>>(0, 1, 2, 3, 4);
+ EXPECT_TRUE((bool)p5);
+ EXPECT_EQ(std::make_tuple(0, 1, 2, 3, 4), *p5);
+
+ auto p6 =
+ make_unique<std::tuple<int, int, int, int, int, int>>(0, 1, 2, 3, 4, 5);
+ EXPECT_TRUE((bool)p6);
+ EXPECT_EQ(std::make_tuple(0, 1, 2, 3, 4, 5), *p6);
+
+ auto p7 = make_unique<std::tuple<int, int, int, int, int, int, int>>(
+ 0, 1, 2, 3, 4, 5, 6);
+ EXPECT_TRUE((bool)p7);
+ EXPECT_EQ(std::make_tuple(0, 1, 2, 3, 4, 5, 6), *p7);
+
+ auto p8 = make_unique<std::tuple<int, int, int, int, int, int, int, int>>(
+ 0, 1, 2, 3, 4, 5, 6, 7);
+ EXPECT_TRUE((bool)p8);
+ EXPECT_EQ(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7), *p8);
+
+ auto p9 =
+ make_unique<std::tuple<int, int, int, int, int, int, int, int, int>>(
+ 0, 1, 2, 3, 4, 5, 6, 7, 8);
+ EXPECT_TRUE((bool)p9);
+ EXPECT_EQ(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8), *p9);
+
+ auto p10 =
+ make_unique<std::tuple<int, int, int, int, int, int, int, int, int, int>>(
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ EXPECT_TRUE((bool)p10);
+ EXPECT_EQ(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), *p10);
+}
+
+TEST(MakeUniqueTest, Array) {
+ auto p1 = make_unique<int[]>(2);
+ EXPECT_TRUE((bool)p1);
+ EXPECT_EQ(0, p1[0]);
+ EXPECT_EQ(0, p1[1]);
+}
+}
diff --git a/unittests/ADT/MapVectorTest.cpp b/unittests/ADT/MapVectorTest.cpp
index 11178bc15e84..92f0dc41910b 100644
--- a/unittests/ADT/MapVectorTest.cpp
+++ b/unittests/ADT/MapVectorTest.cpp
@@ -53,3 +53,39 @@ TEST(MapVectorTest, insert_pop) {
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 7);
}
+
+TEST(MapVectorTest, erase) {
+ MapVector<int, int> MV;
+
+ MV.insert(std::make_pair(1, 2));
+ MV.insert(std::make_pair(3, 4));
+ MV.insert(std::make_pair(5, 6));
+ ASSERT_EQ(MV.size(), 3u);
+
+ MV.erase(MV.find(1));
+ ASSERT_EQ(MV.size(), 2u);
+ ASSERT_EQ(MV.find(1), MV.end());
+ ASSERT_EQ(MV[3], 4);
+ ASSERT_EQ(MV[5], 6);
+}
+
+TEST(MapVectorTest, remove_if) {
+ MapVector<int, int> MV;
+
+ MV.insert(std::make_pair(1, 11));
+ MV.insert(std::make_pair(2, 12));
+ MV.insert(std::make_pair(3, 13));
+ MV.insert(std::make_pair(4, 14));
+ MV.insert(std::make_pair(5, 15));
+ MV.insert(std::make_pair(6, 16));
+ ASSERT_EQ(MV.size(), 6u);
+
+ MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
+ ASSERT_EQ(MV.size(), 3u);
+ ASSERT_EQ(MV.find(1), MV.end());
+ ASSERT_EQ(MV.find(3), MV.end());
+ ASSERT_EQ(MV.find(5), MV.end());
+ ASSERT_EQ(MV[2], 12);
+ ASSERT_EQ(MV[4], 14);
+ ASSERT_EQ(MV[6], 16);
+}
diff --git a/unittests/ADT/OptionalTest.cpp b/unittests/ADT/OptionalTest.cpp
index 21e38475d309..2da408c15e0b 100644
--- a/unittests/ADT/OptionalTest.cpp
+++ b/unittests/ADT/OptionalTest.cpp
@@ -169,7 +169,6 @@ TEST_F(OptionalTest, NullCopyConstructionTest) {
EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
}
-#if LLVM_HAS_RVALUE_REFERENCES
struct MoveOnly {
static unsigned MoveConstructions;
static unsigned Destructions;
@@ -278,7 +277,6 @@ TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
EXPECT_EQ(1u, MoveOnly::MoveAssignments);
EXPECT_EQ(1u, MoveOnly::Destructions);
}
-#endif
} // end anonymous namespace
diff --git a/unittests/ADT/PointerIntPairTest.cpp b/unittests/ADT/PointerIntPairTest.cpp
new file mode 100644
index 000000000000..296d47590d78
--- /dev/null
+++ b/unittests/ADT/PointerIntPairTest.cpp
@@ -0,0 +1,76 @@
+//===- llvm/unittest/ADT/PointerIntPairTest.cpp - Unit tests --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <limits>
+using namespace llvm;
+
+namespace {
+
+// Test fixture
+class PointerIntPairTest : public testing::Test {
+};
+
+TEST_F(PointerIntPairTest, GetSet) {
+ PointerIntPair<PointerIntPairTest *, 2> Pair(this, 1U);
+ EXPECT_EQ(this, Pair.getPointer());
+ EXPECT_EQ(1U, Pair.getInt());
+
+ Pair.setInt(2);
+ EXPECT_EQ(this, Pair.getPointer());
+ EXPECT_EQ(2U, Pair.getInt());
+
+ Pair.setPointer(nullptr);
+ EXPECT_EQ(nullptr, Pair.getPointer());
+ EXPECT_EQ(2U, Pair.getInt());
+
+ Pair.setPointerAndInt(this, 3U);
+ EXPECT_EQ(this, Pair.getPointer());
+ EXPECT_EQ(3U, Pair.getInt());
+}
+
+TEST_F(PointerIntPairTest, DefaultInitialize) {
+ PointerIntPair<PointerIntPairTest *, 2> Pair;
+ EXPECT_EQ(nullptr, Pair.getPointer());
+ EXPECT_EQ(0U, Pair.getInt());
+}
+
+#if !(defined(_MSC_VER) && _MSC_VER==1700)
+TEST_F(PointerIntPairTest, ManyUnusedBits) {
+ // In real code this would be a word-sized integer limited to 31 bits.
+ struct Fixnum31 {
+ uintptr_t Value;
+ };
+ class FixnumPointerTraits {
+ public:
+ static inline void *getAsVoidPointer(Fixnum31 Num) {
+ return reinterpret_cast<void *>(Num.Value << NumLowBitsAvailable);
+ }
+ static inline Fixnum31 getFromVoidPointer(void *P) {
+ // In real code this would assert that the value is in range.
+ return { reinterpret_cast<uintptr_t>(P) >> NumLowBitsAvailable };
+ }
+ enum { NumLowBitsAvailable = std::numeric_limits<uintptr_t>::digits - 31 };
+ };
+
+ PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits> pair;
+ EXPECT_EQ((uintptr_t)0, pair.getPointer().Value);
+ EXPECT_FALSE(pair.getInt());
+
+ pair.setPointerAndInt({ 0x7FFFFFFF }, true );
+ EXPECT_EQ((uintptr_t)0x7FFFFFFF, pair.getPointer().Value);
+ EXPECT_TRUE(pair.getInt());
+
+ EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1,
+ PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
+}
+#endif
+
+} // end anonymous namespace
diff --git a/unittests/ADT/PointerUnionTest.cpp b/unittests/ADT/PointerUnionTest.cpp
index 7eb718112d69..a592784ae095 100644
--- a/unittests/ADT/PointerUnionTest.cpp
+++ b/unittests/ADT/PointerUnionTest.cpp
@@ -13,22 +13,24 @@ using namespace llvm;
namespace {
-typedef PointerUnion<int*, float*> PU;
+typedef PointerUnion<int *, float *> PU;
-// Test fixture
-class PointerUnionTest : public testing::Test {
-};
+struct PointerUnionTest : public testing::Test {
+ float f;
+ int i;
-float f = 3.14f;
-int i = 42;
+ PU a, b, c, n;
-const PU a(&f);
-const PU b(&i);
-const PU n;
+ PointerUnionTest() : f(3.14f), i(42), a(&f), b(&i), c(&i), n() {}
+};
TEST_F(PointerUnionTest, Comparison) {
+ EXPECT_TRUE(a == a);
+ EXPECT_FALSE(a != a);
EXPECT_TRUE(a != b);
EXPECT_FALSE(a == b);
+ EXPECT_TRUE(b == c);
+ EXPECT_FALSE(b != c);
EXPECT_TRUE(b != n);
EXPECT_FALSE(b == n);
}
@@ -44,21 +46,27 @@ TEST_F(PointerUnionTest, Null) {
EXPECT_TRUE((bool)a);
EXPECT_TRUE((bool)b);
EXPECT_FALSE(n);
+
+ EXPECT_NE(n, b);
+ EXPECT_EQ(b, c);
+ b = nullptr;
+ EXPECT_EQ(n, b);
+ EXPECT_NE(b, c);
}
TEST_F(PointerUnionTest, Is) {
- EXPECT_FALSE(a.is<int*>());
- EXPECT_TRUE(a.is<float*>());
- EXPECT_TRUE(b.is<int*>());
- EXPECT_FALSE(b.is<float*>());
- EXPECT_TRUE(n.is<int*>());
- EXPECT_FALSE(n.is<float*>());
+ EXPECT_FALSE(a.is<int *>());
+ EXPECT_TRUE(a.is<float *>());
+ EXPECT_TRUE(b.is<int *>());
+ EXPECT_FALSE(b.is<float *>());
+ EXPECT_TRUE(n.is<int *>());
+ EXPECT_FALSE(n.is<float *>());
}
TEST_F(PointerUnionTest, Get) {
- EXPECT_EQ(a.get<float*>(), &f);
- EXPECT_EQ(b.get<int*>(), &i);
- EXPECT_EQ(n.get<int*>(), (int*)0);
+ EXPECT_EQ(a.get<float *>(), &f);
+ EXPECT_EQ(b.get<int *>(), &i);
+ EXPECT_EQ(n.get<int *>(), (int *)nullptr);
}
} // end anonymous namespace
diff --git a/unittests/ADT/SCCIteratorTest.cpp b/unittests/ADT/SCCIteratorTest.cpp
index 92b4b317cfbd..3f1ba1c5843f 100644
--- a/unittests/ADT/SCCIteratorTest.cpp
+++ b/unittests/ADT/SCCIteratorTest.cpp
@@ -213,7 +213,7 @@ public:
// Return a pointer to it.
return FirstNode + i;
assert(false && "Dereferencing end iterator!");
- return 0; // Avoid compiler warning.
+ return nullptr; // Avoid compiler warning.
}
};
@@ -277,7 +277,7 @@ TEST(SCCIteratorTest, AllSmallGraphs) {
GT::NodeSubset NodesInSomeSCC;
for (scc_iterator<GT> I = scc_begin(G), E = scc_end(G); I != E; ++I) {
- std::vector<GT::NodeType*> &SCC = *I;
+ const std::vector<GT::NodeType *> &SCC = *I;
// Get the nodes in this SCC as a NodeSubset rather than a vector.
GT::NodeSubset NodesInThisSCC;
diff --git a/unittests/ADT/SmallPtrSetTest.cpp b/unittests/ADT/SmallPtrSetTest.cpp
index f85d7c941ebd..fdd1cbb60040 100644
--- a/unittests/ADT/SmallPtrSetTest.cpp
+++ b/unittests/ADT/SmallPtrSetTest.cpp
@@ -16,7 +16,30 @@
using namespace llvm;
-// SmallPtrSet swapping test.
+TEST(SmallPtrSetTest, Assignment) {
+ int buf[8];
+ for (int i = 0; i < 8; ++i)
+ buf[i] = 0;
+
+ SmallPtrSet<int *, 4> s1;
+ s1.insert(&buf[0]);
+ s1.insert(&buf[1]);
+
+ SmallPtrSet<int *, 4> s2;
+ (s2 = s1).insert(&buf[2]);
+
+ // Self assign as well.
+ (s2 = s2).insert(&buf[3]);
+
+ s1 = s2;
+ EXPECT_EQ(4U, s1.size());
+ for (int i = 0; i < 8; ++i)
+ if (i < 4)
+ EXPECT_TRUE(s1.count(&buf[i]));
+ else
+ EXPECT_FALSE(s1.count(&buf[i]));
+}
+
TEST(SmallPtrSetTest, GrowthTest) {
int i;
int buf[8];
@@ -71,6 +94,68 @@ TEST(SmallPtrSetTest, GrowthTest) {
EXPECT_EQ(1,buf[i]);
}
+TEST(SmallPtrSetTest, CopyAndMoveTest) {
+ int buf[8];
+ for (int i = 0; i < 8; ++i)
+ buf[i] = 0;
+
+ SmallPtrSet<int *, 4> s1;
+ s1.insert(&buf[0]);
+ s1.insert(&buf[1]);
+ s1.insert(&buf[2]);
+ s1.insert(&buf[3]);
+ EXPECT_EQ(4U, s1.size());
+ for (int i = 0; i < 8; ++i)
+ if (i < 4)
+ EXPECT_TRUE(s1.count(&buf[i]));
+ else
+ EXPECT_FALSE(s1.count(&buf[i]));
+
+ SmallPtrSet<int *, 4> s2(s1);
+ EXPECT_EQ(4U, s2.size());
+ for (int i = 0; i < 8; ++i)
+ if (i < 4)
+ EXPECT_TRUE(s2.count(&buf[i]));
+ else
+ EXPECT_FALSE(s2.count(&buf[i]));
+
+ s1 = s2;
+ EXPECT_EQ(4U, s1.size());
+ EXPECT_EQ(4U, s2.size());
+ for (int i = 0; i < 8; ++i)
+ if (i < 4)
+ EXPECT_TRUE(s1.count(&buf[i]));
+ else
+ EXPECT_FALSE(s1.count(&buf[i]));
+
+ SmallPtrSet<int *, 4> s3(std::move(s1));
+ EXPECT_EQ(4U, s3.size());
+ EXPECT_TRUE(s1.empty());
+ for (int i = 0; i < 8; ++i)
+ if (i < 4)
+ EXPECT_TRUE(s3.count(&buf[i]));
+ else
+ EXPECT_FALSE(s3.count(&buf[i]));
+
+ // Move assign into the moved-from object. Also test move of a non-small
+ // container.
+ s3.insert(&buf[4]);
+ s3.insert(&buf[5]);
+ s3.insert(&buf[6]);
+ s3.insert(&buf[7]);
+ s1 = std::move(s3);
+ EXPECT_EQ(8U, s1.size());
+ EXPECT_TRUE(s3.empty());
+ for (int i = 0; i < 8; ++i)
+ EXPECT_TRUE(s1.count(&buf[i]));
+
+ // Copy assign into a moved-from object.
+ s3 = s1;
+ EXPECT_EQ(8U, s3.size());
+ EXPECT_EQ(8U, s1.size());
+ for (int i = 0; i < 8; ++i)
+ EXPECT_TRUE(s3.count(&buf[i]));
+}
TEST(SmallPtrSetTest, SwapTest) {
int buf[10];
diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp
index 90c7982699a7..95bf33e5bfba 100644
--- a/unittests/ADT/SmallVectorTest.cpp
+++ b/unittests/ADT/SmallVectorTest.cpp
@@ -26,32 +26,56 @@ namespace {
class Constructable {
private:
static int numConstructorCalls;
+ static int numMoveConstructorCalls;
+ static int numCopyConstructorCalls;
static int numDestructorCalls;
static int numAssignmentCalls;
+ static int numMoveAssignmentCalls;
+ static int numCopyAssignmentCalls;
+ bool constructed;
int value;
public:
- Constructable() : value(0) {
+ Constructable() : constructed(true), value(0) {
++numConstructorCalls;
}
- Constructable(int val) : value(val) {
+ Constructable(int val) : constructed(true), value(val) {
++numConstructorCalls;
}
- Constructable(const Constructable & src) {
+ Constructable(const Constructable & src) : constructed(true) {
value = src.value;
++numConstructorCalls;
+ ++numCopyConstructorCalls;
+ }
+
+ Constructable(Constructable && src) : constructed(true) {
+ value = src.value;
+ ++numConstructorCalls;
+ ++numMoveConstructorCalls;
}
~Constructable() {
+ EXPECT_TRUE(constructed);
++numDestructorCalls;
+ constructed = false;
}
Constructable & operator=(const Constructable & src) {
+ EXPECT_TRUE(constructed);
value = src.value;
++numAssignmentCalls;
+ ++numCopyAssignmentCalls;
+ return *this;
+ }
+
+ Constructable & operator=(Constructable && src) {
+ EXPECT_TRUE(constructed);
+ value = src.value;
+ ++numAssignmentCalls;
+ ++numMoveAssignmentCalls;
return *this;
}
@@ -61,18 +85,42 @@ public:
static void reset() {
numConstructorCalls = 0;
+ numMoveConstructorCalls = 0;
+ numCopyConstructorCalls = 0;
numDestructorCalls = 0;
numAssignmentCalls = 0;
+ numMoveAssignmentCalls = 0;
+ numCopyAssignmentCalls = 0;
}
static int getNumConstructorCalls() {
return numConstructorCalls;
}
+ static int getNumMoveConstructorCalls() {
+ return numMoveConstructorCalls;
+ }
+
+ static int getNumCopyConstructorCalls() {
+ return numCopyConstructorCalls;
+ }
+
static int getNumDestructorCalls() {
return numDestructorCalls;
}
+ static int getNumAssignmentCalls() {
+ return numAssignmentCalls;
+ }
+
+ static int getNumMoveAssignmentCalls() {
+ return numMoveAssignmentCalls;
+ }
+
+ static int getNumCopyAssignmentCalls() {
+ return numCopyAssignmentCalls;
+ }
+
friend bool operator==(const Constructable & c0, const Constructable & c1) {
return c0.getValue() == c1.getValue();
}
@@ -84,8 +132,26 @@ public:
};
int Constructable::numConstructorCalls;
+int Constructable::numCopyConstructorCalls;
+int Constructable::numMoveConstructorCalls;
int Constructable::numDestructorCalls;
int Constructable::numAssignmentCalls;
+int Constructable::numCopyAssignmentCalls;
+int Constructable::numMoveAssignmentCalls;
+
+struct NonCopyable {
+ NonCopyable() {}
+ NonCopyable(NonCopyable &&) {}
+ NonCopyable &operator=(NonCopyable &&) { return *this; }
+private:
+ NonCopyable(const NonCopyable &) LLVM_DELETED_FUNCTION;
+ NonCopyable &operator=(const NonCopyable &) LLVM_DELETED_FUNCTION;
+};
+
+LLVM_ATTRIBUTE_USED void CompileTest() {
+ SmallVector<NonCopyable, 0> V;
+ V.resize(42);
+}
// Test fixture class
template <typename VectorT>
@@ -132,7 +198,8 @@ protected:
typedef ::testing::Types<SmallVector<Constructable, 0>,
SmallVector<Constructable, 1>,
SmallVector<Constructable, 2>,
- SmallVector<Constructable, 4>
+ SmallVector<Constructable, 4>,
+ SmallVector<Constructable, 5>
> SmallVectorTestTypes;
TYPED_TEST_CASE(SmallVectorTest, SmallVectorTestTypes);
@@ -224,13 +291,26 @@ TYPED_TEST(SmallVectorTest, ResizeGrowTest) {
this->theVector.resize(2);
- // The extra constructor/destructor calls come from the temporary object used
- // to initialize the contents of the resized array (via copy construction).
- EXPECT_EQ(3, Constructable::getNumConstructorCalls());
- EXPECT_EQ(1, Constructable::getNumDestructorCalls());
+ EXPECT_EQ(2, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(0, Constructable::getNumDestructorCalls());
EXPECT_EQ(2u, this->theVector.size());
}
+TYPED_TEST(SmallVectorTest, ResizeWithElementsTest) {
+ this->theVector.resize(2);
+
+ Constructable::reset();
+
+ this->theVector.resize(4);
+
+ size_t Ctors = Constructable::getNumConstructorCalls();
+ EXPECT_TRUE(Ctors == 2 || Ctors == 4);
+ size_t MoveCtors = Constructable::getNumMoveConstructorCalls();
+ EXPECT_TRUE(MoveCtors == 0 || MoveCtors == 2);
+ size_t Dtors = Constructable::getNumDestructorCalls();
+ EXPECT_TRUE(Dtors == 0 || Dtors == 2);
+}
+
// Resize with fill value.
TYPED_TEST(SmallVectorTest, ResizeFillTest) {
SCOPED_TRACE("ResizeFillTest");
@@ -338,6 +418,36 @@ TYPED_TEST(SmallVectorTest, AssignTest) {
this->assertValuesInOrder(this->theVector, 2u, 77, 77);
}
+// Move-assign test
+TYPED_TEST(SmallVectorTest, MoveAssignTest) {
+ SCOPED_TRACE("MoveAssignTest");
+
+ // Set up our vector with a single element, but enough capacity for 4.
+ this->theVector.reserve(4);
+ this->theVector.push_back(Constructable(1));
+
+ // Set up the other vector with 2 elements.
+ this->otherVector.push_back(Constructable(2));
+ this->otherVector.push_back(Constructable(3));
+
+ // Move-assign from the other vector.
+ this->theVector = std::move(this->otherVector);
+
+ // Make sure we have the right result.
+ this->assertValuesInOrder(this->theVector, 2u, 2, 3);
+
+ // Make sure the # of constructor/destructor calls line up. There
+ // are two live objects after clearing the other vector.
+ this->otherVector.clear();
+ EXPECT_EQ(Constructable::getNumConstructorCalls()-2,
+ Constructable::getNumDestructorCalls());
+
+ // There shouldn't be any live objects any more.
+ this->theVector.clear();
+ EXPECT_EQ(Constructable::getNumConstructorCalls(),
+ Constructable::getNumDestructorCalls());
+}
+
// Erase a single element
TYPED_TEST(SmallVectorTest, EraseTest) {
SCOPED_TRACE("EraseTest");
@@ -367,22 +477,67 @@ TYPED_TEST(SmallVectorTest, InsertTest) {
this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3);
}
+// Insert a copy of a single element.
+TYPED_TEST(SmallVectorTest, InsertCopy) {
+ SCOPED_TRACE("InsertTest");
+
+ this->makeSequence(this->theVector, 1, 3);
+ Constructable C(77);
+ typename TypeParam::iterator I =
+ this->theVector.insert(this->theVector.begin() + 1, C);
+ EXPECT_EQ(this->theVector.begin() + 1, I);
+ this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3);
+}
+
// Insert repeated elements.
TYPED_TEST(SmallVectorTest, InsertRepeatedTest) {
SCOPED_TRACE("InsertRepeatedTest");
- this->makeSequence(this->theVector, 10, 15);
- typename TypeParam::iterator I =
- this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16));
+ this->makeSequence(this->theVector, 1, 4);
+ Constructable::reset();
+ auto I =
+ this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16));
+ // Move construct the top element into newly allocated space, and optionally
+ // reallocate the whole buffer, move constructing into it.
+ // FIXME: This is inefficient, we shouldn't move things into newly allocated
+ // space, then move them up/around, there should only be 2 or 4 move
+ // constructions here.
+ EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 2 ||
+ Constructable::getNumMoveConstructorCalls() == 6);
+ // Move assign the next two to shift them up and make a gap.
+ EXPECT_EQ(1, Constructable::getNumMoveAssignmentCalls());
+ // Copy construct the two new elements from the parameter.
+ EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls());
+ // All without any copy construction.
+ EXPECT_EQ(0, Constructable::getNumCopyConstructorCalls());
EXPECT_EQ(this->theVector.begin() + 1, I);
- this->assertValuesInOrder(this->theVector, 8u,
- 10, 16, 16, 11, 12, 13, 14, 15);
+ this->assertValuesInOrder(this->theVector, 6u, 1, 16, 16, 2, 3, 4);
+}
- // Insert at end.
- I = this->theVector.insert(this->theVector.end(), 2, Constructable(16));
- EXPECT_EQ(this->theVector.begin() + 8, I);
- this->assertValuesInOrder(this->theVector, 10u,
- 10, 16, 16, 11, 12, 13, 14, 15, 16, 16);
+
+TYPED_TEST(SmallVectorTest, InsertRepeatedAtEndTest) {
+ SCOPED_TRACE("InsertRepeatedTest");
+
+ this->makeSequence(this->theVector, 1, 4);
+ Constructable::reset();
+ auto I = this->theVector.insert(this->theVector.end(), 2, Constructable(16));
+ // Just copy construct them into newly allocated space
+ EXPECT_EQ(2, Constructable::getNumCopyConstructorCalls());
+ // Move everything across if reallocation is needed.
+ EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 ||
+ Constructable::getNumMoveConstructorCalls() == 4);
+ // Without ever moving or copying anything else.
+ EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls());
+ EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls());
+
+ EXPECT_EQ(this->theVector.begin() + 4, I);
+ this->assertValuesInOrder(this->theVector, 6u, 1, 2, 3, 4, 16, 16);
+}
+
+TYPED_TEST(SmallVectorTest, InsertRepeatedEmptyTest) {
+ SCOPED_TRACE("InsertRepeatedTest");
+
+ this->makeSequence(this->theVector, 10, 15);
// Empty insert.
EXPECT_EQ(this->theVector.end(),
@@ -401,16 +556,53 @@ TYPED_TEST(SmallVectorTest, InsertRangeTest) {
{ Constructable(77), Constructable(77), Constructable(77) };
this->makeSequence(this->theVector, 1, 3);
- typename TypeParam::iterator I =
- this->theVector.insert(this->theVector.begin() + 1, Arr, Arr+3);
+ Constructable::reset();
+ auto I = this->theVector.insert(this->theVector.begin() + 1, Arr, Arr + 3);
+ // Move construct the top 3 elements into newly allocated space.
+ // Possibly move the whole sequence into new space first.
+ // FIXME: This is inefficient, we shouldn't move things into newly allocated
+ // space, then move them up/around, there should only be 2 or 3 move
+ // constructions here.
+ EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 2 ||
+ Constructable::getNumMoveConstructorCalls() == 5);
+ // Copy assign the lower 2 new elements into existing space.
+ EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls());
+ // Copy construct the third element into newly allocated space.
+ EXPECT_EQ(1, Constructable::getNumCopyConstructorCalls());
EXPECT_EQ(this->theVector.begin() + 1, I);
this->assertValuesInOrder(this->theVector, 6u, 1, 77, 77, 77, 2, 3);
+}
+
+
+TYPED_TEST(SmallVectorTest, InsertRangeAtEndTest) {
+ SCOPED_TRACE("InsertRangeTest");
+
+ Constructable Arr[3] =
+ { Constructable(77), Constructable(77), Constructable(77) };
+
+ this->makeSequence(this->theVector, 1, 3);
// Insert at end.
- I = this->theVector.insert(this->theVector.end(), Arr, Arr+3);
- EXPECT_EQ(this->theVector.begin() + 6, I);
- this->assertValuesInOrder(this->theVector, 9u,
- 1, 77, 77, 77, 2, 3, 77, 77, 77);
+ Constructable::reset();
+ auto I = this->theVector.insert(this->theVector.end(), Arr, Arr+3);
+ // Copy construct the 3 elements into new space at the top.
+ EXPECT_EQ(3, Constructable::getNumCopyConstructorCalls());
+ // Don't copy/move anything else.
+ EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls());
+ // Reallocation might occur, causing all elements to be moved into the new
+ // buffer.
+ EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 ||
+ Constructable::getNumMoveConstructorCalls() == 3);
+ EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls());
+ EXPECT_EQ(this->theVector.begin() + 3, I);
+ this->assertValuesInOrder(this->theVector, 6u,
+ 1, 2, 3, 77, 77, 77);
+}
+
+TYPED_TEST(SmallVectorTest, InsertEmptyRangeTest) {
+ SCOPED_TRACE("InsertRangeTest");
+
+ this->makeSequence(this->theVector, 1, 3);
// Empty insert.
EXPECT_EQ(this->theVector.end(),
@@ -455,13 +647,12 @@ TYPED_TEST(SmallVectorTest, DirectVectorTest) {
this->theVector.reserve(4);
EXPECT_LE(4u, this->theVector.capacity());
EXPECT_EQ(0, Constructable::getNumConstructorCalls());
- this->theVector.end()[0] = 1;
- this->theVector.end()[1] = 2;
- this->theVector.end()[2] = 3;
- this->theVector.end()[3] = 4;
- this->theVector.set_size(4);
+ this->theVector.push_back(1);
+ this->theVector.push_back(2);
+ this->theVector.push_back(3);
+ this->theVector.push_back(4);
EXPECT_EQ(4u, this->theVector.size());
- EXPECT_EQ(4, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(8, Constructable::getNumConstructorCalls());
EXPECT_EQ(1, this->theVector[0].getValue());
EXPECT_EQ(2, this->theVector[1].getValue());
EXPECT_EQ(3, this->theVector[2].getValue());
@@ -486,4 +677,26 @@ TEST(SmallVectorCustomTest, NoAssignTest) {
EXPECT_EQ(42, vec.pop_back_val().x);
}
+struct MovedFrom {
+ bool hasValue;
+ MovedFrom() : hasValue(true) {
+ }
+ MovedFrom(MovedFrom&& m) : hasValue(m.hasValue) {
+ m.hasValue = false;
+ }
+ MovedFrom &operator=(MovedFrom&& m) {
+ hasValue = m.hasValue;
+ m.hasValue = false;
+ return *this;
+ }
+};
+
+TEST(SmallVectorTest, MidInsert) {
+ SmallVector<MovedFrom, 3> v;
+ v.push_back(MovedFrom());
+ v.insert(v.begin(), MovedFrom());
+ for (MovedFrom &m : v)
+ EXPECT_TRUE(m.hasValue);
+}
+
}
diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp
index 5bb65cbd7aa3..028375d7b4be 100644
--- a/unittests/ADT/StringMapTest.cpp
+++ b/unittests/ADT/StringMapTest.cpp
@@ -10,6 +10,7 @@
#include "gtest/gtest.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/DataTypes.h"
+#include <tuple>
using namespace llvm;
namespace {
@@ -183,28 +184,11 @@ TEST_F(StringMapTest, IterationTest) {
}
}
-} // end anonymous namespace
-
-namespace llvm {
-
-template <>
-class StringMapEntryInitializer<uint32_t> {
-public:
- template <typename InitTy>
- static void Initialize(StringMapEntry<uint32_t> &T, InitTy InitVal) {
- T.second = InitVal;
- }
-};
-
-} // end llvm namespace
-
-namespace {
-
// Test StringMapEntry::Create() method.
TEST_F(StringMapTest, StringMapEntryTest) {
StringMap<uint32_t>::value_type* entry =
StringMap<uint32_t>::value_type::Create(
- testKeyFirst, testKeyFirst + testKeyLength, 1u);
+ StringRef(testKeyFirst, testKeyLength), 1u);
EXPECT_STREQ(testKey, entry->first().data());
EXPECT_EQ(1u, entry->second);
free(entry);
@@ -215,9 +199,149 @@ TEST_F(StringMapTest, InsertTest) {
SCOPED_TRACE("InsertTest");
testMap.insert(
StringMap<uint32_t>::value_type::Create(
- testKeyFirst, testKeyFirst + testKeyLength,
+ StringRef(testKeyFirst, testKeyLength),
testMap.getAllocator(), 1u));
assertSingleItemMap();
}
+// Test insert(pair<K, V>) method
+TEST_F(StringMapTest, InsertPairTest) {
+ bool Inserted;
+ StringMap<uint32_t>::iterator NewIt;
+ std::tie(NewIt, Inserted) =
+ testMap.insert(std::make_pair(testKeyFirst, testValue));
+ EXPECT_EQ(1u, testMap.size());
+ EXPECT_EQ(testValue, testMap[testKeyFirst]);
+ EXPECT_EQ(testKeyFirst, NewIt->first());
+ EXPECT_EQ(testValue, NewIt->second);
+ EXPECT_TRUE(Inserted);
+
+ StringMap<uint32_t>::iterator ExistingIt;
+ std::tie(ExistingIt, Inserted) =
+ testMap.insert(std::make_pair(testKeyFirst, testValue + 1));
+ EXPECT_EQ(1u, testMap.size());
+ EXPECT_EQ(testValue, testMap[testKeyFirst]);
+ EXPECT_FALSE(Inserted);
+ EXPECT_EQ(NewIt, ExistingIt);
+}
+
+// Test insert(pair<K, V>) method when rehashing occurs
+TEST_F(StringMapTest, InsertRehashingPairTest) {
+ // Check that the correct iterator is returned when the inserted element is
+ // moved to a different bucket during internal rehashing. This depends on
+ // the particular key, and the implementation of StringMap and HashString.
+ // Changes to those might result in this test not actually checking that.
+ StringMap<uint32_t> t(1);
+ EXPECT_EQ(1u, t.getNumBuckets());
+
+ StringMap<uint32_t>::iterator It =
+ t.insert(std::make_pair("abcdef", 42)).first;
+ EXPECT_EQ(2u, t.getNumBuckets());
+ EXPECT_EQ("abcdef", It->first());
+ EXPECT_EQ(42u, It->second);
+}
+
+// Create a non-default constructable value
+struct StringMapTestStruct {
+ StringMapTestStruct(int i) : i(i) {}
+ StringMapTestStruct() LLVM_DELETED_FUNCTION;
+ int i;
+};
+
+TEST_F(StringMapTest, NonDefaultConstructable) {
+ StringMap<StringMapTestStruct> t;
+ t.GetOrCreateValue("Test", StringMapTestStruct(123));
+ StringMap<StringMapTestStruct>::iterator iter = t.find("Test");
+ ASSERT_NE(iter, t.end());
+ ASSERT_EQ(iter->second.i, 123);
+}
+
+struct MoveOnly {
+ int i;
+ MoveOnly(int i) : i(i) {}
+ MoveOnly(MoveOnly &&RHS) : i(RHS.i) {}
+ MoveOnly &operator=(MoveOnly &&RHS) {
+ i = RHS.i;
+ return *this;
+ }
+
+private:
+ MoveOnly(const MoveOnly &) LLVM_DELETED_FUNCTION;
+ MoveOnly &operator=(const MoveOnly &) LLVM_DELETED_FUNCTION;
+};
+
+TEST_F(StringMapTest, MoveOnlyKey) {
+ StringMap<MoveOnly> t;
+ t.GetOrCreateValue("Test", MoveOnly(42));
+ StringRef Key = "Test";
+ StringMapEntry<MoveOnly>::Create(Key, MoveOnly(42))
+ ->Destroy();
+}
+
+TEST_F(StringMapTest, MoveConstruct) {
+ StringMap<int> A;
+ A.GetOrCreateValue("x", 42);
+ StringMap<int> B = std::move(A);
+ ASSERT_EQ(A.size(), 0u);
+ ASSERT_EQ(B.size(), 1u);
+ ASSERT_EQ(B["x"], 42);
+ ASSERT_EQ(B.count("y"), 0u);
+}
+
+TEST_F(StringMapTest, MoveAssignment) {
+ StringMap<int> A;
+ A["x"] = 42;
+ StringMap<int> B;
+ B["y"] = 117;
+ A = std::move(B);
+ ASSERT_EQ(A.size(), 1u);
+ ASSERT_EQ(B.size(), 0u);
+ ASSERT_EQ(A["y"], 117);
+ ASSERT_EQ(B.count("x"), 0u);
+}
+
+struct Countable {
+ int &InstanceCount;
+ int Number;
+ Countable(int Number, int &InstanceCount)
+ : InstanceCount(InstanceCount), Number(Number) {
+ ++InstanceCount;
+ }
+ Countable(Countable &&C) : InstanceCount(C.InstanceCount), Number(C.Number) {
+ ++InstanceCount;
+ C.Number = -1;
+ }
+ Countable(const Countable &C)
+ : InstanceCount(C.InstanceCount), Number(C.Number) {
+ ++InstanceCount;
+ }
+ Countable &operator=(Countable C) {
+ Number = C.Number;
+ return *this;
+ }
+ ~Countable() { --InstanceCount; }
+};
+
+TEST_F(StringMapTest, MoveDtor) {
+ int InstanceCount = 0;
+ StringMap<Countable> A;
+ A.GetOrCreateValue("x", Countable(42, InstanceCount));
+ ASSERT_EQ(InstanceCount, 1);
+ auto I = A.find("x");
+ ASSERT_NE(I, A.end());
+ ASSERT_EQ(I->second.Number, 42);
+
+ StringMap<Countable> B;
+ B = std::move(A);
+ ASSERT_EQ(InstanceCount, 1);
+ ASSERT_TRUE(A.empty());
+ I = B.find("x");
+ ASSERT_NE(I, B.end());
+ ASSERT_EQ(I->second.Number, 42);
+
+ B = StringMap<Countable>();
+ ASSERT_EQ(InstanceCount, 0);
+ ASSERT_TRUE(B.empty());
+}
+
} // end anonymous namespace
diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp
index 88691ae19749..d80179bd7873 100644
--- a/unittests/ADT/StringRefTest.cpp
+++ b/unittests/ADT/StringRefTest.cpp
@@ -8,9 +8,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -531,4 +533,18 @@ TEST(StringRefTest, joinStrings) {
EXPECT_TRUE(v2_join3);
}
+
+TEST(StringRefTest, AllocatorCopy) {
+ BumpPtrAllocator Alloc;
+ StringRef Str1 = "hello";
+ StringRef Str2 = "bye";
+ StringRef Str1c = Str1.copy(Alloc);
+ StringRef Str2c = Str2.copy(Alloc);
+ EXPECT_TRUE(Str1.equals(Str1c));
+ EXPECT_NE(Str1.data(), Str1c.data());
+ EXPECT_TRUE(Str2.equals(Str2c));
+ EXPECT_NE(Str2.data(), Str2c.data());
+}
+
+
} // end anonymous namespace
diff --git a/unittests/ADT/TinyPtrVectorTest.cpp b/unittests/ADT/TinyPtrVectorTest.cpp
index a4f92ffbe383..ec868d4258a2 100644
--- a/unittests/ADT/TinyPtrVectorTest.cpp
+++ b/unittests/ADT/TinyPtrVectorTest.cpp
@@ -36,7 +36,7 @@ template <typename VectorT>
class TinyPtrVectorTest : public testing::Test {
protected:
typedef typename VectorT::value_type PtrT;
- typedef typename remove_pointer<PtrT>::type ValueT;
+ typedef typename std::remove_pointer<PtrT>::type ValueT;
VectorT V;
VectorT V2;
@@ -72,9 +72,9 @@ protected:
EXPECT_EQ(Values.size(), V.size());
for (size_t i = 0, e = Values.size(); i != e; ++i) {
EXPECT_EQ(Values[i], V[i]);
- EXPECT_EQ(Values[i], *llvm::next(V.begin(), i));
+ EXPECT_EQ(Values[i], *std::next(V.begin(), i));
}
- EXPECT_EQ(V.end(), llvm::next(V.begin(), Values.size()));
+ EXPECT_EQ(V.end(), std::next(V.begin(), Values.size()));
}
};
@@ -157,170 +157,136 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveCtorTest) {
this->expectValues(Copy2, this->testArray(42));
this->expectValues(this->V2, this->testArray(0));
-#if LLVM_HAS_RVALUE_REFERENCES
TypeParam Move(std::move(Copy2));
this->expectValues(Move, this->testArray(42));
this->expectValues(Copy2, this->testArray(0));
-#endif
}
TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) {
this->V = this->V2;
this->expectValues(this->V, this->testArray(0));
this->expectValues(this->V2, this->testArray(0));
-#if LLVM_HAS_RVALUE_REFERENCES
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(0));
-#endif
this->setVectors(this->testArray(1), this->testArray(0));
this->V = this->V2;
this->expectValues(this->V, this->testArray(0));
this->expectValues(this->V2, this->testArray(0));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(1), this->testArray(0));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(0));
-#endif
this->setVectors(this->testArray(2), this->testArray(0));
this->V = this->V2;
this->expectValues(this->V, this->testArray(0));
this->expectValues(this->V2, this->testArray(0));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(2), this->testArray(0));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(0));
-#endif
this->setVectors(this->testArray(42), this->testArray(0));
this->V = this->V2;
this->expectValues(this->V, this->testArray(0));
this->expectValues(this->V2, this->testArray(0));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(42), this->testArray(0));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(0));
-#endif
this->setVectors(this->testArray(0), this->testArray(1));
this->V = this->V2;
this->expectValues(this->V, this->testArray(1));
this->expectValues(this->V2, this->testArray(1));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(0), this->testArray(1));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(1));
-#endif
this->setVectors(this->testArray(0), this->testArray(2));
this->V = this->V2;
this->expectValues(this->V, this->testArray(2));
this->expectValues(this->V2, this->testArray(2));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(0), this->testArray(2));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(2));
-#endif
this->setVectors(this->testArray(0), this->testArray(42));
this->V = this->V2;
this->expectValues(this->V, this->testArray(42));
this->expectValues(this->V2, this->testArray(42));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(0), this->testArray(42));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(42));
-#endif
this->setVectors(this->testArray(1), this->testArray(1));
this->V = this->V2;
this->expectValues(this->V, this->testArray(1));
this->expectValues(this->V2, this->testArray(1));
-#if LLVM_HAS_RVALUE_REFERENCES
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(1));
-#endif
this->setVectors(this->testArray(1), this->testArray(2));
this->V = this->V2;
this->expectValues(this->V, this->testArray(2));
this->expectValues(this->V2, this->testArray(2));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(1), this->testArray(2));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(2));
-#endif
this->setVectors(this->testArray(1), this->testArray(42));
this->V = this->V2;
this->expectValues(this->V, this->testArray(42));
this->expectValues(this->V2, this->testArray(42));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(1), this->testArray(42));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(42));
-#endif
this->setVectors(this->testArray(2), this->testArray(1));
this->V = this->V2;
this->expectValues(this->V, this->testArray(1));
this->expectValues(this->V2, this->testArray(1));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(2), this->testArray(1));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(1));
-#endif
this->setVectors(this->testArray(2), this->testArray(2));
this->V = this->V2;
this->expectValues(this->V, this->testArray(2));
this->expectValues(this->V2, this->testArray(2));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(2), this->testArray(2));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(2));
-#endif
this->setVectors(this->testArray(2), this->testArray(42));
this->V = this->V2;
this->expectValues(this->V, this->testArray(42));
this->expectValues(this->V2, this->testArray(42));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(2), this->testArray(42));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(42));
-#endif
this->setVectors(this->testArray(42), this->testArray(1));
this->V = this->V2;
this->expectValues(this->V, this->testArray(1));
this->expectValues(this->V2, this->testArray(1));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(42), this->testArray(1));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(1));
-#endif
this->setVectors(this->testArray(42), this->testArray(2));
this->V = this->V2;
this->expectValues(this->V, this->testArray(2));
this->expectValues(this->V2, this->testArray(2));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(42), this->testArray(2));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(2));
-#endif
this->setVectors(this->testArray(42), this->testArray(42));
this->V = this->V2;
this->expectValues(this->V, this->testArray(42));
this->expectValues(this->V2, this->testArray(42));
-#if LLVM_HAS_RVALUE_REFERENCES
this->setVectors(this->testArray(42), this->testArray(42));
this->V = std::move(this->V2);
this->expectValues(this->V, this->testArray(42));
-#endif
}
TYPED_TEST(TinyPtrVectorTest, EraseTest) {
@@ -334,17 +300,17 @@ TYPED_TEST(TinyPtrVectorTest, EraseTest) {
this->V.erase(this->V.begin());
this->TestPtrs.erase(this->TestPtrs.begin());
this->expectValues(this->V, this->testArray(41));
- this->V.erase(llvm::next(this->V.begin(), 1));
- this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 1));
+ this->V.erase(std::next(this->V.begin(), 1));
+ this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 1));
this->expectValues(this->V, this->testArray(40));
- this->V.erase(llvm::next(this->V.begin(), 2));
- this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 2));
+ this->V.erase(std::next(this->V.begin(), 2));
+ this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 2));
this->expectValues(this->V, this->testArray(39));
- this->V.erase(llvm::next(this->V.begin(), 5));
- this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 5));
+ this->V.erase(std::next(this->V.begin(), 5));
+ this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 5));
this->expectValues(this->V, this->testArray(38));
- this->V.erase(llvm::next(this->V.begin(), 13));
- this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 13));
+ this->V.erase(std::next(this->V.begin(), 13));
+ this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 13));
this->expectValues(this->V, this->testArray(37));
typename TypeParam::iterator I = this->V.begin();
@@ -366,27 +332,27 @@ TYPED_TEST(TinyPtrVectorTest, EraseRangeTest) {
this->appendValues(this->V, this->testArray(42));
this->expectValues(this->V, this->testArray(42));
- this->V.erase(this->V.begin(), llvm::next(this->V.begin(), 1));
+ this->V.erase(this->V.begin(), std::next(this->V.begin(), 1));
this->TestPtrs.erase(this->TestPtrs.begin(),
- llvm::next(this->TestPtrs.begin(), 1));
+ std::next(this->TestPtrs.begin(), 1));
this->expectValues(this->V, this->testArray(41));
- this->V.erase(llvm::next(this->V.begin(), 1), llvm::next(this->V.begin(), 2));
- this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 1),
- llvm::next(this->TestPtrs.begin(), 2));
+ this->V.erase(std::next(this->V.begin(), 1), std::next(this->V.begin(), 2));
+ this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 1),
+ std::next(this->TestPtrs.begin(), 2));
this->expectValues(this->V, this->testArray(40));
- this->V.erase(llvm::next(this->V.begin(), 2), llvm::next(this->V.begin(), 4));
- this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 2),
- llvm::next(this->TestPtrs.begin(), 4));
+ this->V.erase(std::next(this->V.begin(), 2), std::next(this->V.begin(), 4));
+ this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 2),
+ std::next(this->TestPtrs.begin(), 4));
this->expectValues(this->V, this->testArray(38));
- this->V.erase(llvm::next(this->V.begin(), 5), llvm::next(this->V.begin(), 10));
- this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 5),
- llvm::next(this->TestPtrs.begin(), 10));
+ this->V.erase(std::next(this->V.begin(), 5), std::next(this->V.begin(), 10));
+ this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 5),
+ std::next(this->TestPtrs.begin(), 10));
this->expectValues(this->V, this->testArray(33));
- this->V.erase(llvm::next(this->V.begin(), 13), llvm::next(this->V.begin(), 26));
- this->TestPtrs.erase(llvm::next(this->TestPtrs.begin(), 13),
- llvm::next(this->TestPtrs.begin(), 26));
+ this->V.erase(std::next(this->V.begin(), 13), std::next(this->V.begin(), 26));
+ this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 13),
+ std::next(this->TestPtrs.begin(), 26));
this->expectValues(this->V, this->testArray(20));
- this->V.erase(llvm::next(this->V.begin(), 7), this->V.end());
+ this->V.erase(std::next(this->V.begin(), 7), this->V.end());
this->expectValues(this->V, this->testArray(7));
this->V.erase(this->V.begin(), this->V.end());
this->expectValues(this->V, this->testArray(0));
@@ -403,8 +369,8 @@ TYPED_TEST(TinyPtrVectorTest, Insert) {
this->V.insert(this->V.begin(), this->TestPtrs[42]);
this->TestPtrs.insert(this->TestPtrs.begin(), this->TestPtrs[42]);
this->expectValues(this->V, this->testArray(6));
- this->V.insert(llvm::next(this->V.begin(), 3), this->TestPtrs[43]);
- this->TestPtrs.insert(llvm::next(this->TestPtrs.begin(), 3),
+ this->V.insert(std::next(this->V.begin(), 3), this->TestPtrs[43]);
+ this->TestPtrs.insert(std::next(this->TestPtrs.begin(), 3),
this->TestPtrs[43]);
this->expectValues(this->V, this->testArray(7));
}
@@ -418,30 +384,30 @@ TYPED_TEST(TinyPtrVectorTest, InsertRange) {
this->V.insert(this->V.end(), this->TestPtrs.end(), this->TestPtrs.end());
this->expectValues(this->V, this->testArray(0));
this->V.insert(this->V.end(), this->TestPtrs.begin(),
- llvm::next(this->TestPtrs.begin()));
+ std::next(this->TestPtrs.begin()));
this->expectValues(this->V, this->testArray(1));
this->V.clear();
this->V.insert(this->V.end(), this->TestPtrs.begin(),
- llvm::next(this->TestPtrs.begin(), 2));
+ std::next(this->TestPtrs.begin(), 2));
this->expectValues(this->V, this->testArray(2));
this->V.clear();
this->V.insert(this->V.end(), this->TestPtrs.begin(),
- llvm::next(this->TestPtrs.begin(), 42));
+ std::next(this->TestPtrs.begin(), 42));
this->expectValues(this->V, this->testArray(42));
this->V.clear();
this->V.insert(this->V.end(),
- llvm::next(this->TestPtrs.begin(), 5),
- llvm::next(this->TestPtrs.begin(), 13));
+ std::next(this->TestPtrs.begin(), 5),
+ std::next(this->TestPtrs.begin(), 13));
this->V.insert(this->V.begin(),
- llvm::next(this->TestPtrs.begin(), 0),
- llvm::next(this->TestPtrs.begin(), 3));
- this->V.insert(llvm::next(this->V.begin(), 2),
- llvm::next(this->TestPtrs.begin(), 2),
- llvm::next(this->TestPtrs.begin(), 4));
- this->V.erase(llvm::next(this->V.begin(), 4));
- this->V.insert(llvm::next(this->V.begin(), 4),
- llvm::next(this->TestPtrs.begin(), 4),
- llvm::next(this->TestPtrs.begin(), 5));
+ std::next(this->TestPtrs.begin(), 0),
+ std::next(this->TestPtrs.begin(), 3));
+ this->V.insert(std::next(this->V.begin(), 2),
+ std::next(this->TestPtrs.begin(), 2),
+ std::next(this->TestPtrs.begin(), 4));
+ this->V.erase(std::next(this->V.begin(), 4));
+ this->V.insert(std::next(this->V.begin(), 4),
+ std::next(this->TestPtrs.begin(), 4),
+ std::next(this->TestPtrs.begin(), 5));
this->expectValues(this->V, this->testArray(13));
}
diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp
index b4028963908c..dfc99837d4bc 100644
--- a/unittests/ADT/TripleTest.cpp
+++ b/unittests/ADT/TripleTest.cpp
@@ -190,6 +190,9 @@ TEST(TripleTest, Normalization) {
++Vendor) {
C[1] = Triple::getVendorTypeName(Triple::VendorType(Vendor));
for (int OS = 1+Triple::UnknownOS; OS <= Triple::Minix; ++OS) {
+ if (OS == Triple::Cygwin || OS == Triple::MinGW32 || OS == Triple::Win32)
+ continue;
+
C[2] = Triple::getOSTypeName(Triple::OSType(OS));
std::string E = Join(C[0], C[1], C[2]);
@@ -201,7 +204,7 @@ TEST(TripleTest, Normalization) {
EXPECT_EQ(E, Triple::normalize(Join(C[2], C[0], C[1])));
EXPECT_EQ(E, Triple::normalize(Join(C[2], C[1], C[0])));
- for (int Env = 1+Triple::UnknownEnvironment; Env <= Triple::MachO;
+ for (int Env = 1 + Triple::UnknownEnvironment; Env <= Triple::Android;
++Env) {
C[3] = Triple::getEnvironmentTypeName(Triple::EnvironmentType(Env));
@@ -238,7 +241,7 @@ TEST(TripleTest, Normalization) {
// Various real-world funky triples. The value returned by GCC's config.sub
// is given in the comment.
- EXPECT_EQ("i386--mingw32", Triple::normalize("i386-mingw32")); // i386-pc-mingw32
+ EXPECT_EQ("i386--windows-gnu", Triple::normalize("i386-mingw32")); // i386-pc-mingw32
EXPECT_EQ("x86_64--linux-gnu", Triple::normalize("x86_64-linux-gnu")); // x86_64-pc-linux-gnu
EXPECT_EQ("i486--linux-gnu", Triple::normalize("i486-linux-gnu")); // i486-pc-linux-gnu
EXPECT_EQ("i386-redhat-linux", Triple::normalize("i386-redhat-linux")); // i386-redhat-linux-gnu
@@ -349,10 +352,6 @@ TEST(TripleTest, BitWidthArchVariants) {
EXPECT_EQ(Triple::UnknownArch, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch());
- T.setArch(Triple::arm);
- EXPECT_EQ(Triple::arm, T.get32BitArchVariant().getArch());
- EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch());
-
T.setArch(Triple::mips);
EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch());
@@ -417,7 +416,7 @@ TEST(TripleTest, getOSVersion) {
EXPECT_EQ((unsigned)5, Minor);
EXPECT_EQ((unsigned)0, Micro);
T.getiOSVersion(Major, Minor, Micro);
- EXPECT_EQ((unsigned)3, Major);
+ EXPECT_EQ((unsigned)5, Major);
EXPECT_EQ((unsigned)0, Minor);
EXPECT_EQ((unsigned)0, Micro);
@@ -432,7 +431,7 @@ TEST(TripleTest, getOSVersion) {
EXPECT_EQ((unsigned)5, Minor);
EXPECT_EQ((unsigned)0, Micro);
T.getiOSVersion(Major, Minor, Micro);
- EXPECT_EQ((unsigned)3, Major);
+ EXPECT_EQ((unsigned)5, Major);
EXPECT_EQ((unsigned)0, Minor);
EXPECT_EQ((unsigned)0, Micro);
@@ -447,7 +446,7 @@ TEST(TripleTest, getOSVersion) {
EXPECT_EQ((unsigned)4, Minor);
EXPECT_EQ((unsigned)0, Micro);
T.getiOSVersion(Major, Minor, Micro);
- EXPECT_EQ((unsigned)3, Major);
+ EXPECT_EQ((unsigned)5, Major);
EXPECT_EQ((unsigned)0, Minor);
EXPECT_EQ((unsigned)0, Micro);
@@ -462,7 +461,7 @@ TEST(TripleTest, getOSVersion) {
EXPECT_EQ((unsigned)7, Minor);
EXPECT_EQ((unsigned)0, Micro);
T.getiOSVersion(Major, Minor, Micro);
- EXPECT_EQ((unsigned)3, Major);
+ EXPECT_EQ((unsigned)5, Major);
EXPECT_EQ((unsigned)0, Minor);
EXPECT_EQ((unsigned)0, Micro);
@@ -477,11 +476,11 @@ TEST(TripleTest, getOSVersion) {
EXPECT_EQ((unsigned)4, Minor);
EXPECT_EQ((unsigned)0, Micro);
T.getiOSVersion(Major, Minor, Micro);
- EXPECT_EQ((unsigned)3, Major);
+ EXPECT_EQ((unsigned)5, Major);
EXPECT_EQ((unsigned)0, Minor);
EXPECT_EQ((unsigned)0, Micro);
- T = Triple("armv7-apple-ios5.0");
+ T = Triple("armv7-apple-ios7.0");
EXPECT_FALSE(T.isMacOSX());
EXPECT_TRUE(T.isiOS());
EXPECT_FALSE(T.isArch16Bit());
@@ -492,9 +491,89 @@ TEST(TripleTest, getOSVersion) {
EXPECT_EQ((unsigned)4, Minor);
EXPECT_EQ((unsigned)0, Micro);
T.getiOSVersion(Major, Minor, Micro);
- EXPECT_EQ((unsigned)5, Major);
+ EXPECT_EQ((unsigned)7, Major);
EXPECT_EQ((unsigned)0, Minor);
EXPECT_EQ((unsigned)0, Micro);
}
+TEST(TripleTest, FileFormat) {
+ EXPECT_EQ(Triple::ELF, Triple("i686-unknown-linux-gnu").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686-unknown-freebsd").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686-unknown-netbsd").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686--win32-elf").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686---elf").getObjectFormat());
+
+ EXPECT_EQ(Triple::MachO, Triple("i686-apple-macosx").getObjectFormat());
+ EXPECT_EQ(Triple::MachO, Triple("i686-apple-ios").getObjectFormat());
+ EXPECT_EQ(Triple::MachO, Triple("i686---macho").getObjectFormat());
+
+ EXPECT_EQ(Triple::COFF, Triple("i686--win32").getObjectFormat());
+
+ EXPECT_EQ(Triple::ELF, Triple("i686-pc-windows-msvc-elf").getObjectFormat());
+ EXPECT_EQ(Triple::ELF, Triple("i686-pc-cygwin-elf").getObjectFormat());
+
+ Triple MSVCNormalized(Triple::normalize("i686-pc-windows-msvc-elf"));
+ EXPECT_EQ(Triple::ELF, MSVCNormalized.getObjectFormat());
+
+ Triple GNUWindowsNormalized(Triple::normalize("i686-pc-windows-gnu-elf"));
+ EXPECT_EQ(Triple::ELF, GNUWindowsNormalized.getObjectFormat());
+
+ Triple CygnusNormalised(Triple::normalize("i686-pc-windows-cygnus-elf"));
+ EXPECT_EQ(Triple::ELF, CygnusNormalised.getObjectFormat());
+
+ Triple CygwinNormalized(Triple::normalize("i686-pc-cygwin-elf"));
+ EXPECT_EQ(Triple::ELF, CygwinNormalized.getObjectFormat());
+
+ Triple T = Triple("");
+ T.setObjectFormat(Triple::ELF);
+ EXPECT_EQ(Triple::ELF, T.getObjectFormat());
+}
+
+TEST(TripleTest, NormalizeWindows) {
+ EXPECT_EQ("i686-pc-windows-msvc", Triple::normalize("i686-pc-win32"));
+ EXPECT_EQ("i686--windows-msvc", Triple::normalize("i686-win32"));
+ EXPECT_EQ("i686-pc-windows-gnu", Triple::normalize("i686-pc-mingw32"));
+ EXPECT_EQ("i686--windows-gnu", Triple::normalize("i686-mingw32"));
+ EXPECT_EQ("i686-pc-windows-gnu", Triple::normalize("i686-pc-mingw32-w64"));
+ EXPECT_EQ("i686--windows-gnu", Triple::normalize("i686-mingw32-w64"));
+ EXPECT_EQ("i686-pc-windows-cygnus", Triple::normalize("i686-pc-cygwin"));
+ EXPECT_EQ("i686--windows-cygnus", Triple::normalize("i686-cygwin"));
+
+ EXPECT_EQ("x86_64-pc-windows-msvc", Triple::normalize("x86_64-pc-win32"));
+ EXPECT_EQ("x86_64--windows-msvc", Triple::normalize("x86_64-win32"));
+ EXPECT_EQ("x86_64-pc-windows-gnu", Triple::normalize("x86_64-pc-mingw32"));
+ EXPECT_EQ("x86_64--windows-gnu", Triple::normalize("x86_64-mingw32"));
+ EXPECT_EQ("x86_64-pc-windows-gnu", Triple::normalize("x86_64-pc-mingw32-w64"));
+ EXPECT_EQ("x86_64--windows-gnu", Triple::normalize("x86_64-mingw32-w64"));
+
+ EXPECT_EQ("i686-pc-windows-elf", Triple::normalize("i686-pc-win32-elf"));
+ EXPECT_EQ("i686--windows-elf", Triple::normalize("i686-win32-elf"));
+ EXPECT_EQ("i686-pc-windows-macho", Triple::normalize("i686-pc-win32-macho"));
+ EXPECT_EQ("i686--windows-macho", Triple::normalize("i686-win32-macho"));
+
+ EXPECT_EQ("x86_64-pc-windows-elf", Triple::normalize("x86_64-pc-win32-elf"));
+ EXPECT_EQ("x86_64--windows-elf", Triple::normalize("x86_64-win32-elf"));
+ EXPECT_EQ("x86_64-pc-windows-macho", Triple::normalize("x86_64-pc-win32-macho"));
+ EXPECT_EQ("x86_64--windows-macho", Triple::normalize("x86_64-win32-macho"));
+
+ EXPECT_EQ("i686-pc-windows-cygnus",
+ Triple::normalize("i686-pc-windows-cygnus"));
+ EXPECT_EQ("i686-pc-windows-gnu", Triple::normalize("i686-pc-windows-gnu"));
+ EXPECT_EQ("i686-pc-windows-itanium", Triple::normalize("i686-pc-windows-itanium"));
+ EXPECT_EQ("i686-pc-windows-msvc", Triple::normalize("i686-pc-windows-msvc"));
+
+ EXPECT_EQ("i686-pc-windows-elf", Triple::normalize("i686-pc-windows-elf-elf"));
+}
+
+TEST(TripleTest, getARMCPUForArch) {
+ {
+ llvm::Triple Triple("armv7s-apple-ios7");
+ EXPECT_STREQ("swift", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7-apple-ios7");
+ EXPECT_STREQ("cortex-a8", Triple.getARMCPUForArch());
+ EXPECT_STREQ("swift", Triple.getARMCPUForArch("armv7s"));
+ }
+}
}
diff --git a/unittests/ADT/ilistTest.cpp b/unittests/ADT/ilistTest.cpp
index 0c0cd0fd56fe..44442ebf75ad 100644
--- a/unittests/ADT/ilistTest.cpp
+++ b/unittests/ADT/ilistTest.cpp
@@ -29,8 +29,8 @@ TEST(ilistTest, Basic) {
ilist<Node> List;
List.push_back(Node(1));
EXPECT_EQ(1, List.back().Value);
- EXPECT_EQ(0, List.back().getPrevNode());
- EXPECT_EQ(0, List.back().getNextNode());
+ EXPECT_EQ(nullptr, List.back().getPrevNode());
+ EXPECT_EQ(nullptr, List.back().getNextNode());
List.push_back(Node(2));
EXPECT_EQ(2, List.back().Value);
@@ -51,15 +51,15 @@ TEST(ilistTest, SpliceOne) {
List.splice(List.begin(), List, List.begin());
EXPECT_EQ(1u, List.size());
EXPECT_EQ(1, List.front().Value);
- EXPECT_TRUE(llvm::next(List.begin()) == List.end());
+ EXPECT_TRUE(std::next(List.begin()) == List.end());
// Altenative noop. Move the first element behind itself.
List.push_back(2);
List.push_back(3);
- List.splice(llvm::next(List.begin()), List, List.begin());
+ List.splice(std::next(List.begin()), List, List.begin());
EXPECT_EQ(3u, List.size());
EXPECT_EQ(1, List.front().Value);
- EXPECT_EQ(2, llvm::next(List.begin())->Value);
+ EXPECT_EQ(2, std::next(List.begin())->Value);
EXPECT_EQ(3, List.back().Value);
}
diff --git a/unittests/ADT/polymorphic_ptr_test.cpp b/unittests/ADT/polymorphic_ptr_test.cpp
deleted file mode 100644
index bd5d83879a83..000000000000
--- a/unittests/ADT/polymorphic_ptr_test.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-//===- llvm/unittest/ADT/polymorphic_ptr.h - polymorphic_ptr<T> tests -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "gtest/gtest.h"
-#include "llvm/ADT/polymorphic_ptr.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
-namespace {
-
-struct S {
- S(int x) : x(x) {}
- S *clone() { return new S(*this); }
- int x;
-};
-
-// A function that forces the return of a copy.
-template <typename T>
-T dummy_copy(const T &arg) { return arg; }
-
-TEST(polymorphic_ptr_test, Basic) {
- polymorphic_ptr<S> null;
- EXPECT_FALSE((bool)null);
- EXPECT_TRUE(!null);
- EXPECT_EQ((S*)0, null.get());
-
- S *s = new S(42);
- polymorphic_ptr<S> p(s);
- EXPECT_TRUE((bool)p);
- EXPECT_FALSE(!p);
- EXPECT_TRUE(p != null);
- EXPECT_FALSE(p == null);
- EXPECT_TRUE(p == s);
- EXPECT_TRUE(s == p);
- EXPECT_FALSE(p != s);
- EXPECT_FALSE(s != p);
- EXPECT_EQ(s, &*p);
- EXPECT_EQ(s, p.operator->());
- EXPECT_EQ(s, p.get());
- EXPECT_EQ(42, p->x);
-
- EXPECT_EQ(s, p.take());
- EXPECT_FALSE((bool)p);
- EXPECT_TRUE(!p);
- p = s;
- EXPECT_TRUE((bool)p);
- EXPECT_FALSE(!p);
- EXPECT_EQ(s, &*p);
- EXPECT_EQ(s, p.operator->());
- EXPECT_EQ(s, p.get());
- EXPECT_EQ(42, p->x);
-
- polymorphic_ptr<S> p2((llvm_move(p)));
-#if !LLVM_HAS_RVALUE_REFERENCES
- // 'p' may not have been moved from in C++98, fake it for the test.
- p2 = p.take();
-#endif
- EXPECT_FALSE((bool)p);
- EXPECT_TRUE(!p);
- EXPECT_TRUE((bool)p2);
- EXPECT_FALSE(!p2);
- EXPECT_EQ(s, &*p2);
-
- using std::swap;
- swap(p, p2);
- EXPECT_TRUE((bool)p);
- EXPECT_FALSE(!p);
- EXPECT_EQ(s, &*p);
- EXPECT_FALSE((bool)p2);
- EXPECT_TRUE(!p2);
-
- // Force copies and that everything survives.
- polymorphic_ptr<S> p3 = dummy_copy(polymorphic_ptr<S>(p));
- EXPECT_TRUE((bool)p3);
- EXPECT_FALSE(!p3);
- EXPECT_NE(s, &*p3);
- EXPECT_EQ(42, p3->x);
-
- // Force copies of null without trying to dereference anything.
- polymorphic_ptr<S> null_copy = dummy_copy(polymorphic_ptr<S>(null));
- EXPECT_FALSE((bool)null_copy);
- EXPECT_TRUE(!null_copy);
- EXPECT_EQ(null, null_copy);
-}
-
-struct Base {
- virtual ~Base() {}
- virtual Base *clone() = 0;
- virtual StringRef name() { return "Base"; }
-};
-
-struct DerivedA : Base {
- virtual DerivedA *clone() { return new DerivedA(); }
- virtual StringRef name() { return "DerivedA"; }
-};
-struct DerivedB : Base {
- virtual DerivedB *clone() { return new DerivedB(); }
- virtual StringRef name() { return "DerivedB"; }
-};
-
-TEST(polymorphic_ptr_test, Polymorphism) {
- polymorphic_ptr<Base> a(new DerivedA());
- polymorphic_ptr<Base> b(new DerivedB());
-
- EXPECT_EQ("DerivedA", a->name());
- EXPECT_EQ("DerivedB", b->name());
-
- polymorphic_ptr<Base> copy = dummy_copy(a);
- EXPECT_NE(a, copy);
- EXPECT_EQ("DerivedA", copy->name());
-
- copy = dummy_copy(b);
- EXPECT_NE(b, copy);
- EXPECT_EQ("DerivedB", copy->name());
-
- // Test creating a copy out of a temporary directly.
- copy = dummy_copy<polymorphic_ptr<Base> >(new DerivedA());
- EXPECT_NE(a, copy);
- EXPECT_EQ("DerivedA", copy->name());
-}
-
-}
diff --git a/unittests/Analysis/CFGTest.cpp b/unittests/Analysis/CFGTest.cpp
index e931709620f3..ac5e71061d8a 100644
--- a/unittests/Analysis/CFGTest.cpp
+++ b/unittests/Analysis/CFGTest.cpp
@@ -8,18 +8,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/CFG.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Assembly/Parser.h"
-#include "llvm/IR/LLVMContext.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/InstIterator.h"
-#include "llvm/Support/SourceMgr.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -47,10 +46,10 @@ protected:
}
Function *F = M->getFunction("test");
- if (F == NULL)
+ if (F == nullptr)
report_fatal_error("Test must have a function named @test");
- A = B = NULL;
+ A = B = nullptr;
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
if (I->hasName()) {
if (I->getName() == "A")
@@ -59,9 +58,9 @@ protected:
B = &*I;
}
}
- if (A == NULL)
+ if (A == nullptr)
report_fatal_error("@test must have an instruction %A");
- if (B == NULL)
+ if (B == nullptr)
report_fatal_error("@test must have an instruction %B");
}
@@ -75,17 +74,18 @@ protected:
static int initialize() {
PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass",
- "", &ID, 0, true, true);
+ "", &ID, nullptr, true, true);
PassRegistry::getPassRegistry()->registerPass(*PI, false);
initializeLoopInfoPass(*PassRegistry::getPassRegistry());
- initializeDominatorTreePass(*PassRegistry::getPassRegistry());
+ initializeDominatorTreeWrapperPassPass(
+ *PassRegistry::getPassRegistry());
return 0;
}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<LoopInfo>();
- AU.addRequired<DominatorTree>();
+ AU.addRequired<DominatorTreeWrapperPass>();
}
bool runOnFunction(Function &F) {
@@ -93,10 +93,12 @@ protected:
return false;
LoopInfo *LI = &getAnalysis<LoopInfo>();
- DominatorTree *DT = &getAnalysis<DominatorTree>();
- EXPECT_EQ(isPotentiallyReachable(A, B, 0, 0), ExpectedResult);
- EXPECT_EQ(isPotentiallyReachable(A, B, DT, 0), ExpectedResult);
- EXPECT_EQ(isPotentiallyReachable(A, B, 0, LI), ExpectedResult);
+ DominatorTree *DT =
+ &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, nullptr),
+ ExpectedResult);
+ EXPECT_EQ(isPotentiallyReachable(A, B, DT, nullptr), ExpectedResult);
+ EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, LI), ExpectedResult);
EXPECT_EQ(isPotentiallyReachable(A, B, DT, LI), ExpectedResult);
return false;
}
@@ -113,8 +115,8 @@ protected:
PM.add(P);
PM.run(*M);
}
-private:
- OwningPtr<Module> M;
+
+ std::unique_ptr<Module> M;
Instruction *A, *B;
};
@@ -350,27 +352,40 @@ TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOtherInsideAThirdLoop) {
ExpectPath(true);
}
+static const char *BranchInsideLoopIR =
+ "declare i1 @switch()\n"
+ "\n"
+ "define void @test() {\n"
+ "entry:\n"
+ " br label %loop\n"
+ "loop:\n"
+ " %x = call i1 @switch()\n"
+ " br i1 %x, label %nextloopblock, label %exit\n"
+ "nextloopblock:\n"
+ " %y = call i1 @switch()\n"
+ " br i1 %y, label %left, label %right\n"
+ "left:\n"
+ " %A = bitcast i8 undef to i8\n"
+ " br label %loop\n"
+ "right:\n"
+ " %B = bitcast i8 undef to i8\n"
+ " br label %loop\n"
+ "exit:\n"
+ " ret void\n"
+ "}";
+
TEST_F(IsPotentiallyReachableTest, BranchInsideLoop) {
- ParseAssembly(
- "declare i1 @switch()\n"
- "\n"
- "define void @test() {\n"
- "entry:\n"
- " br label %loop\n"
- "loop:\n"
- " %x = call i1 @switch()\n"
- " br i1 %x, label %nextloopblock, label %exit\n"
- "nextloopblock:\n"
- " %y = call i1 @switch()\n"
- " br i1 %y, label %left, label %right\n"
- "left:\n"
- " %A = bitcast i8 undef to i8\n"
- " br label %loop\n"
- "right:\n"
- " %B = bitcast i8 undef to i8\n"
- " br label %loop\n"
- "exit:\n"
- " ret void\n"
- "}");
+ ParseAssembly(BranchInsideLoopIR);
+ ExpectPath(true);
+}
+
+TEST_F(IsPotentiallyReachableTest, ModifyTest) {
+ ParseAssembly(BranchInsideLoopIR);
+
+ succ_iterator S = succ_begin(++M->getFunction("test")->begin());
+ BasicBlock *OldBB = S[0];
+ S[0] = S[1];
+ ExpectPath(false);
+ S[0] = OldBB;
ExpectPath(true);
}
diff --git a/unittests/Analysis/CMakeLists.txt b/unittests/Analysis/CMakeLists.txt
index 7e5b35852749..84548609edea 100644
--- a/unittests/Analysis/CMakeLists.txt
+++ b/unittests/Analysis/CMakeLists.txt
@@ -1,9 +1,13 @@
set(LLVM_LINK_COMPONENTS
Analysis
AsmParser
+ Core
+ Support
)
add_llvm_unittest(AnalysisTests
CFGTest.cpp
+ LazyCallGraphTest.cpp
ScalarEvolutionTest.cpp
+ MixedTBAATest.cpp
)
diff --git a/unittests/Analysis/LazyCallGraphTest.cpp b/unittests/Analysis/LazyCallGraphTest.cpp
new file mode 100644
index 000000000000..d7c70453c9b0
--- /dev/null
+++ b/unittests/Analysis/LazyCallGraphTest.cpp
@@ -0,0 +1,720 @@
+//===- LazyCallGraphTest.cpp - Unit tests for the lazy CG analysis --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+std::unique_ptr<Module> parseAssembly(const char *Assembly) {
+ auto M = make_unique<Module>("Module", getGlobalContext());
+
+ SMDiagnostic Error;
+ bool Parsed =
+ ParseAssemblyString(Assembly, M.get(), Error, M->getContext()) == M.get();
+
+ std::string ErrMsg;
+ raw_string_ostream OS(ErrMsg);
+ Error.print("", OS);
+
+ // A failure here means that the test itself is buggy.
+ if (!Parsed)
+ report_fatal_error(OS.str().c_str());
+
+ return M;
+}
+
+// IR forming a call graph with a diamond of triangle-shaped SCCs:
+//
+// d1
+// / \
+// d3--d2
+// / \
+// b1 c1
+// / \ / \
+// b3--b2 c3--c2
+// \ /
+// a1
+// / \
+// a3--a2
+//
+// All call edges go up between SCCs, and clockwise around the SCC.
+static const char DiamondOfTriangles[] =
+ "define void @a1() {\n"
+ "entry:\n"
+ " call void @a2()\n"
+ " call void @b2()\n"
+ " call void @c3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @a2() {\n"
+ "entry:\n"
+ " call void @a3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @a3() {\n"
+ "entry:\n"
+ " call void @a1()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b1() {\n"
+ "entry:\n"
+ " call void @b2()\n"
+ " call void @d3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b2() {\n"
+ "entry:\n"
+ " call void @b3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b3() {\n"
+ "entry:\n"
+ " call void @b1()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c1() {\n"
+ "entry:\n"
+ " call void @c2()\n"
+ " call void @d2()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c2() {\n"
+ "entry:\n"
+ " call void @c3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c3() {\n"
+ "entry:\n"
+ " call void @c1()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d1() {\n"
+ "entry:\n"
+ " call void @d2()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d2() {\n"
+ "entry:\n"
+ " call void @d3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d3() {\n"
+ "entry:\n"
+ " call void @d1()\n"
+ " ret void\n"
+ "}\n";
+
+TEST(LazyCallGraphTest, BasicGraphFormation) {
+ std::unique_ptr<Module> M = parseAssembly(DiamondOfTriangles);
+ LazyCallGraph CG(*M);
+
+ // The order of the entry nodes should be stable w.r.t. the source order of
+ // the IR, and everything in our module is an entry node, so just directly
+ // build variables for each node.
+ auto I = CG.begin();
+ LazyCallGraph::Node &A1 = *I++;
+ EXPECT_EQ("a1", A1.getFunction().getName());
+ LazyCallGraph::Node &A2 = *I++;
+ EXPECT_EQ("a2", A2.getFunction().getName());
+ LazyCallGraph::Node &A3 = *I++;
+ EXPECT_EQ("a3", A3.getFunction().getName());
+ LazyCallGraph::Node &B1 = *I++;
+ EXPECT_EQ("b1", B1.getFunction().getName());
+ LazyCallGraph::Node &B2 = *I++;
+ EXPECT_EQ("b2", B2.getFunction().getName());
+ LazyCallGraph::Node &B3 = *I++;
+ EXPECT_EQ("b3", B3.getFunction().getName());
+ LazyCallGraph::Node &C1 = *I++;
+ EXPECT_EQ("c1", C1.getFunction().getName());
+ LazyCallGraph::Node &C2 = *I++;
+ EXPECT_EQ("c2", C2.getFunction().getName());
+ LazyCallGraph::Node &C3 = *I++;
+ EXPECT_EQ("c3", C3.getFunction().getName());
+ LazyCallGraph::Node &D1 = *I++;
+ EXPECT_EQ("d1", D1.getFunction().getName());
+ LazyCallGraph::Node &D2 = *I++;
+ EXPECT_EQ("d2", D2.getFunction().getName());
+ LazyCallGraph::Node &D3 = *I++;
+ EXPECT_EQ("d3", D3.getFunction().getName());
+ EXPECT_EQ(CG.end(), I);
+
+ // Build vectors and sort them for the rest of the assertions to make them
+ // independent of order.
+ std::vector<std::string> Nodes;
+
+ for (LazyCallGraph::Node &N : A1)
+ Nodes.push_back(N.getFunction().getName());
+ std::sort(Nodes.begin(), Nodes.end());
+ EXPECT_EQ("a2", Nodes[0]);
+ EXPECT_EQ("b2", Nodes[1]);
+ EXPECT_EQ("c3", Nodes[2]);
+ Nodes.clear();
+
+ EXPECT_EQ(A2.end(), std::next(A2.begin()));
+ EXPECT_EQ("a3", A2.begin()->getFunction().getName());
+ EXPECT_EQ(A3.end(), std::next(A3.begin()));
+ EXPECT_EQ("a1", A3.begin()->getFunction().getName());
+
+ for (LazyCallGraph::Node &N : B1)
+ Nodes.push_back(N.getFunction().getName());
+ std::sort(Nodes.begin(), Nodes.end());
+ EXPECT_EQ("b2", Nodes[0]);
+ EXPECT_EQ("d3", Nodes[1]);
+ Nodes.clear();
+
+ EXPECT_EQ(B2.end(), std::next(B2.begin()));
+ EXPECT_EQ("b3", B2.begin()->getFunction().getName());
+ EXPECT_EQ(B3.end(), std::next(B3.begin()));
+ EXPECT_EQ("b1", B3.begin()->getFunction().getName());
+
+ for (LazyCallGraph::Node &N : C1)
+ Nodes.push_back(N.getFunction().getName());
+ std::sort(Nodes.begin(), Nodes.end());
+ EXPECT_EQ("c2", Nodes[0]);
+ EXPECT_EQ("d2", Nodes[1]);
+ Nodes.clear();
+
+ EXPECT_EQ(C2.end(), std::next(C2.begin()));
+ EXPECT_EQ("c3", C2.begin()->getFunction().getName());
+ EXPECT_EQ(C3.end(), std::next(C3.begin()));
+ EXPECT_EQ("c1", C3.begin()->getFunction().getName());
+
+ EXPECT_EQ(D1.end(), std::next(D1.begin()));
+ EXPECT_EQ("d2", D1.begin()->getFunction().getName());
+ EXPECT_EQ(D2.end(), std::next(D2.begin()));
+ EXPECT_EQ("d3", D2.begin()->getFunction().getName());
+ EXPECT_EQ(D3.end(), std::next(D3.begin()));
+ EXPECT_EQ("d1", D3.begin()->getFunction().getName());
+
+ // Now lets look at the SCCs.
+ auto SCCI = CG.postorder_scc_begin();
+
+ LazyCallGraph::SCC &D = *SCCI++;
+ for (LazyCallGraph::Node *N : D)
+ Nodes.push_back(N->getFunction().getName());
+ std::sort(Nodes.begin(), Nodes.end());
+ EXPECT_EQ(3u, Nodes.size());
+ EXPECT_EQ("d1", Nodes[0]);
+ EXPECT_EQ("d2", Nodes[1]);
+ EXPECT_EQ("d3", Nodes[2]);
+ Nodes.clear();
+ EXPECT_FALSE(D.isParentOf(D));
+ EXPECT_FALSE(D.isChildOf(D));
+ EXPECT_FALSE(D.isAncestorOf(D));
+ EXPECT_FALSE(D.isDescendantOf(D));
+
+ LazyCallGraph::SCC &C = *SCCI++;
+ for (LazyCallGraph::Node *N : C)
+ Nodes.push_back(N->getFunction().getName());
+ std::sort(Nodes.begin(), Nodes.end());
+ EXPECT_EQ(3u, Nodes.size());
+ EXPECT_EQ("c1", Nodes[0]);
+ EXPECT_EQ("c2", Nodes[1]);
+ EXPECT_EQ("c3", Nodes[2]);
+ Nodes.clear();
+ EXPECT_TRUE(C.isParentOf(D));
+ EXPECT_FALSE(C.isChildOf(D));
+ EXPECT_TRUE(C.isAncestorOf(D));
+ EXPECT_FALSE(C.isDescendantOf(D));
+
+ LazyCallGraph::SCC &B = *SCCI++;
+ for (LazyCallGraph::Node *N : B)
+ Nodes.push_back(N->getFunction().getName());
+ std::sort(Nodes.begin(), Nodes.end());
+ EXPECT_EQ(3u, Nodes.size());
+ EXPECT_EQ("b1", Nodes[0]);
+ EXPECT_EQ("b2", Nodes[1]);
+ EXPECT_EQ("b3", Nodes[2]);
+ Nodes.clear();
+ EXPECT_TRUE(B.isParentOf(D));
+ EXPECT_FALSE(B.isChildOf(D));
+ EXPECT_TRUE(B.isAncestorOf(D));
+ EXPECT_FALSE(B.isDescendantOf(D));
+ EXPECT_FALSE(B.isAncestorOf(C));
+ EXPECT_FALSE(C.isAncestorOf(B));
+
+ LazyCallGraph::SCC &A = *SCCI++;
+ for (LazyCallGraph::Node *N : A)
+ Nodes.push_back(N->getFunction().getName());
+ std::sort(Nodes.begin(), Nodes.end());
+ EXPECT_EQ(3u, Nodes.size());
+ EXPECT_EQ("a1", Nodes[0]);
+ EXPECT_EQ("a2", Nodes[1]);
+ EXPECT_EQ("a3", Nodes[2]);
+ Nodes.clear();
+ EXPECT_TRUE(A.isParentOf(B));
+ EXPECT_TRUE(A.isParentOf(C));
+ EXPECT_FALSE(A.isParentOf(D));
+ EXPECT_TRUE(A.isAncestorOf(B));
+ EXPECT_TRUE(A.isAncestorOf(C));
+ EXPECT_TRUE(A.isAncestorOf(D));
+
+ EXPECT_EQ(CG.postorder_scc_end(), SCCI);
+}
+
+static Function &lookupFunction(Module &M, StringRef Name) {
+ for (Function &F : M)
+ if (F.getName() == Name)
+ return F;
+ report_fatal_error("Couldn't find function!");
+}
+
+TEST(LazyCallGraphTest, BasicGraphMutation) {
+ std::unique_ptr<Module> M = parseAssembly(
+ "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG(*M);
+
+ LazyCallGraph::Node &A = CG.get(lookupFunction(*M, "a"));
+ LazyCallGraph::Node &B = CG.get(lookupFunction(*M, "b"));
+ EXPECT_EQ(2, std::distance(A.begin(), A.end()));
+ EXPECT_EQ(0, std::distance(B.begin(), B.end()));
+
+ CG.insertEdge(B, lookupFunction(*M, "c"));
+ EXPECT_EQ(1, std::distance(B.begin(), B.end()));
+ LazyCallGraph::Node &C = *B.begin();
+ EXPECT_EQ(0, std::distance(C.begin(), C.end()));
+
+ CG.insertEdge(C, B.getFunction());
+ EXPECT_EQ(1, std::distance(C.begin(), C.end()));
+ EXPECT_EQ(&B, &*C.begin());
+
+ CG.insertEdge(C, C.getFunction());
+ EXPECT_EQ(2, std::distance(C.begin(), C.end()));
+ EXPECT_EQ(&B, &*C.begin());
+ EXPECT_EQ(&C, &*std::next(C.begin()));
+
+ CG.removeEdge(C, B.getFunction());
+ EXPECT_EQ(1, std::distance(C.begin(), C.end()));
+ EXPECT_EQ(&C, &*C.begin());
+
+ CG.removeEdge(C, C.getFunction());
+ EXPECT_EQ(0, std::distance(C.begin(), C.end()));
+
+ CG.removeEdge(B, C.getFunction());
+ EXPECT_EQ(0, std::distance(B.begin(), B.end()));
+}
+
+TEST(LazyCallGraphTest, MultiArmSCC) {
+ // Two interlocking cycles. The really useful thing about this SCC is that it
+ // will require Tarjan's DFS to backtrack and finish processing all of the
+ // children of each node in the SCC.
+ std::unique_ptr<Module> M = parseAssembly(
+ "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d() {\n"
+ "entry:\n"
+ " call void @e()\n"
+ " ret void\n"
+ "}\n"
+ "define void @e() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG(*M);
+
+ // Force the graph to be fully expanded.
+ auto SCCI = CG.postorder_scc_begin();
+ LazyCallGraph::SCC &SCC = *SCCI++;
+ EXPECT_EQ(CG.postorder_scc_end(), SCCI);
+
+ LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
+ LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
+ LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
+ LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
+ LazyCallGraph::Node &E = *CG.lookup(lookupFunction(*M, "e"));
+ EXPECT_EQ(&SCC, CG.lookupSCC(A));
+ EXPECT_EQ(&SCC, CG.lookupSCC(B));
+ EXPECT_EQ(&SCC, CG.lookupSCC(C));
+ EXPECT_EQ(&SCC, CG.lookupSCC(D));
+ EXPECT_EQ(&SCC, CG.lookupSCC(E));
+}
+
+TEST(LazyCallGraphTest, OutgoingSCCEdgeInsertion) {
+ std::unique_ptr<Module> M = parseAssembly(
+ "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d() {\n"
+ "entry:\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG(*M);
+
+ // Force the graph to be fully expanded.
+ for (LazyCallGraph::SCC &C : CG.postorder_sccs())
+ (void)C;
+
+ LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
+ LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
+ LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
+ LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
+ LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
+ LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
+ LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
+ LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
+ EXPECT_TRUE(AC.isAncestorOf(BC));
+ EXPECT_TRUE(AC.isAncestorOf(CC));
+ EXPECT_TRUE(AC.isAncestorOf(DC));
+ EXPECT_TRUE(DC.isDescendantOf(AC));
+ EXPECT_TRUE(DC.isDescendantOf(BC));
+ EXPECT_TRUE(DC.isDescendantOf(CC));
+
+ EXPECT_EQ(2, std::distance(A.begin(), A.end()));
+ AC.insertOutgoingEdge(A, D);
+ EXPECT_EQ(3, std::distance(A.begin(), A.end()));
+ EXPECT_TRUE(AC.isParentOf(DC));
+ EXPECT_EQ(&AC, CG.lookupSCC(A));
+ EXPECT_EQ(&BC, CG.lookupSCC(B));
+ EXPECT_EQ(&CC, CG.lookupSCC(C));
+ EXPECT_EQ(&DC, CG.lookupSCC(D));
+}
+
+TEST(LazyCallGraphTest, IncomingSCCEdgeInsertion) {
+ // We want to ensure we can add edges even across complex diamond graphs, so
+ // we use the diamond of triangles graph defined above. The ascii diagram is
+ // repeated here for easy reference.
+ //
+ // d1 |
+ // / \ |
+ // d3--d2 |
+ // / \ |
+ // b1 c1 |
+ // / \ / \ |
+ // b3--b2 c3--c2 |
+ // \ / |
+ // a1 |
+ // / \ |
+ // a3--a2 |
+ //
+ std::unique_ptr<Module> M = parseAssembly(DiamondOfTriangles);
+ LazyCallGraph CG(*M);
+
+ // Force the graph to be fully expanded.
+ for (LazyCallGraph::SCC &C : CG.postorder_sccs())
+ (void)C;
+
+ LazyCallGraph::Node &A1 = *CG.lookup(lookupFunction(*M, "a1"));
+ LazyCallGraph::Node &A2 = *CG.lookup(lookupFunction(*M, "a2"));
+ LazyCallGraph::Node &A3 = *CG.lookup(lookupFunction(*M, "a3"));
+ LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
+ LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
+ LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
+ LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
+ LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
+ LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
+ LazyCallGraph::Node &D1 = *CG.lookup(lookupFunction(*M, "d1"));
+ LazyCallGraph::Node &D2 = *CG.lookup(lookupFunction(*M, "d2"));
+ LazyCallGraph::Node &D3 = *CG.lookup(lookupFunction(*M, "d3"));
+ LazyCallGraph::SCC &AC = *CG.lookupSCC(A1);
+ LazyCallGraph::SCC &BC = *CG.lookupSCC(B1);
+ LazyCallGraph::SCC &CC = *CG.lookupSCC(C1);
+ LazyCallGraph::SCC &DC = *CG.lookupSCC(D1);
+ ASSERT_EQ(&AC, CG.lookupSCC(A2));
+ ASSERT_EQ(&AC, CG.lookupSCC(A3));
+ ASSERT_EQ(&BC, CG.lookupSCC(B2));
+ ASSERT_EQ(&BC, CG.lookupSCC(B3));
+ ASSERT_EQ(&CC, CG.lookupSCC(C2));
+ ASSERT_EQ(&CC, CG.lookupSCC(C3));
+ ASSERT_EQ(&DC, CG.lookupSCC(D2));
+ ASSERT_EQ(&DC, CG.lookupSCC(D3));
+ ASSERT_EQ(1, std::distance(D2.begin(), D2.end()));
+
+ // Add an edge to make the graph:
+ //
+ // d1 |
+ // / \ |
+ // d3--d2---. |
+ // / \ | |
+ // b1 c1 | |
+ // / \ / \ / |
+ // b3--b2 c3--c2 |
+ // \ / |
+ // a1 |
+ // / \ |
+ // a3--a2 |
+ CC.insertIncomingEdge(D2, C2);
+ // Make sure we connected the nodes.
+ EXPECT_EQ(2, std::distance(D2.begin(), D2.end()));
+
+ // Make sure we have the correct nodes in the SCC sets.
+ EXPECT_EQ(&AC, CG.lookupSCC(A1));
+ EXPECT_EQ(&AC, CG.lookupSCC(A2));
+ EXPECT_EQ(&AC, CG.lookupSCC(A3));
+ EXPECT_EQ(&BC, CG.lookupSCC(B1));
+ EXPECT_EQ(&BC, CG.lookupSCC(B2));
+ EXPECT_EQ(&BC, CG.lookupSCC(B3));
+ EXPECT_EQ(&CC, CG.lookupSCC(C1));
+ EXPECT_EQ(&CC, CG.lookupSCC(C2));
+ EXPECT_EQ(&CC, CG.lookupSCC(C3));
+ EXPECT_EQ(&CC, CG.lookupSCC(D1));
+ EXPECT_EQ(&CC, CG.lookupSCC(D2));
+ EXPECT_EQ(&CC, CG.lookupSCC(D3));
+
+ // And that ancestry tests have been updated.
+ EXPECT_TRUE(AC.isParentOf(BC));
+ EXPECT_TRUE(AC.isParentOf(CC));
+ EXPECT_FALSE(AC.isAncestorOf(DC));
+ EXPECT_FALSE(BC.isAncestorOf(DC));
+ EXPECT_FALSE(CC.isAncestorOf(DC));
+}
+
+TEST(LazyCallGraphTest, IncomingSCCEdgeInsertionMidTraversal) {
+ // This is the same fundamental test as the previous, but we perform it
+ // having only partially walked the SCCs of the graph.
+ std::unique_ptr<Module> M = parseAssembly(DiamondOfTriangles);
+ LazyCallGraph CG(*M);
+
+ // Walk the SCCs until we find the one containing 'c1'.
+ auto SCCI = CG.postorder_scc_begin(), SCCE = CG.postorder_scc_end();
+ ASSERT_NE(SCCI, SCCE);
+ LazyCallGraph::SCC &DC = *SCCI;
+ ASSERT_NE(&DC, nullptr);
+ ++SCCI;
+ ASSERT_NE(SCCI, SCCE);
+ LazyCallGraph::SCC &CC = *SCCI;
+ ASSERT_NE(&CC, nullptr);
+
+ ASSERT_EQ(nullptr, CG.lookup(lookupFunction(*M, "a1")));
+ ASSERT_EQ(nullptr, CG.lookup(lookupFunction(*M, "a2")));
+ ASSERT_EQ(nullptr, CG.lookup(lookupFunction(*M, "a3")));
+ ASSERT_EQ(nullptr, CG.lookup(lookupFunction(*M, "b1")));
+ ASSERT_EQ(nullptr, CG.lookup(lookupFunction(*M, "b2")));
+ ASSERT_EQ(nullptr, CG.lookup(lookupFunction(*M, "b3")));
+ LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
+ LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
+ LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
+ LazyCallGraph::Node &D1 = *CG.lookup(lookupFunction(*M, "d1"));
+ LazyCallGraph::Node &D2 = *CG.lookup(lookupFunction(*M, "d2"));
+ LazyCallGraph::Node &D3 = *CG.lookup(lookupFunction(*M, "d3"));
+ ASSERT_EQ(&CC, CG.lookupSCC(C1));
+ ASSERT_EQ(&CC, CG.lookupSCC(C2));
+ ASSERT_EQ(&CC, CG.lookupSCC(C3));
+ ASSERT_EQ(&DC, CG.lookupSCC(D1));
+ ASSERT_EQ(&DC, CG.lookupSCC(D2));
+ ASSERT_EQ(&DC, CG.lookupSCC(D3));
+ ASSERT_EQ(1, std::distance(D2.begin(), D2.end()));
+
+ CC.insertIncomingEdge(D2, C2);
+ EXPECT_EQ(2, std::distance(D2.begin(), D2.end()));
+
+ // Make sure we have the correct nodes in the SCC sets.
+ EXPECT_EQ(&CC, CG.lookupSCC(C1));
+ EXPECT_EQ(&CC, CG.lookupSCC(C2));
+ EXPECT_EQ(&CC, CG.lookupSCC(C3));
+ EXPECT_EQ(&CC, CG.lookupSCC(D1));
+ EXPECT_EQ(&CC, CG.lookupSCC(D2));
+ EXPECT_EQ(&CC, CG.lookupSCC(D3));
+
+ // Check that we can form the last two SCCs now in a coherent way.
+ ++SCCI;
+ EXPECT_NE(SCCI, SCCE);
+ LazyCallGraph::SCC &BC = *SCCI;
+ EXPECT_NE(&BC, nullptr);
+ EXPECT_EQ(&BC, CG.lookupSCC(*CG.lookup(lookupFunction(*M, "b1"))));
+ EXPECT_EQ(&BC, CG.lookupSCC(*CG.lookup(lookupFunction(*M, "b2"))));
+ EXPECT_EQ(&BC, CG.lookupSCC(*CG.lookup(lookupFunction(*M, "b3"))));
+ ++SCCI;
+ EXPECT_NE(SCCI, SCCE);
+ LazyCallGraph::SCC &AC = *SCCI;
+ EXPECT_NE(&AC, nullptr);
+ EXPECT_EQ(&AC, CG.lookupSCC(*CG.lookup(lookupFunction(*M, "a1"))));
+ EXPECT_EQ(&AC, CG.lookupSCC(*CG.lookup(lookupFunction(*M, "a2"))));
+ EXPECT_EQ(&AC, CG.lookupSCC(*CG.lookup(lookupFunction(*M, "a3"))));
+ ++SCCI;
+ EXPECT_EQ(SCCI, SCCE);
+}
+
+TEST(LazyCallGraphTest, InterSCCEdgeRemoval) {
+ std::unique_ptr<Module> M = parseAssembly(
+ "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG(*M);
+
+ // Force the graph to be fully expanded.
+ for (LazyCallGraph::SCC &C : CG.postorder_sccs())
+ (void)C;
+
+ LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
+ LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
+ LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
+ LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
+
+ EXPECT_EQ("b", A.begin()->getFunction().getName());
+ EXPECT_EQ(B.end(), B.begin());
+ EXPECT_EQ(&AC, &*BC.parent_begin());
+
+ AC.removeInterSCCEdge(A, B);
+
+ EXPECT_EQ(A.end(), A.begin());
+ EXPECT_EQ(B.end(), B.begin());
+ EXPECT_EQ(BC.parent_end(), BC.parent_begin());
+}
+
+TEST(LazyCallGraphTest, IntraSCCEdgeInsertion) {
+ std::unique_ptr<Module> M1 = parseAssembly(
+ "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG1(*M1);
+
+ // Force the graph to be fully expanded.
+ auto SCCI = CG1.postorder_scc_begin();
+ LazyCallGraph::SCC &SCC = *SCCI++;
+ EXPECT_EQ(CG1.postorder_scc_end(), SCCI);
+
+ LazyCallGraph::Node &A = *CG1.lookup(lookupFunction(*M1, "a"));
+ LazyCallGraph::Node &B = *CG1.lookup(lookupFunction(*M1, "b"));
+ LazyCallGraph::Node &C = *CG1.lookup(lookupFunction(*M1, "c"));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(A));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(B));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(C));
+
+ // Insert an edge from 'a' to 'c'. Nothing changes about the SCCs.
+ SCC.insertIntraSCCEdge(A, C);
+ EXPECT_EQ(2, std::distance(A.begin(), A.end()));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(A));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(B));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(C));
+
+ // Insert a self edge from 'a' back to 'a'.
+ SCC.insertIntraSCCEdge(A, A);
+ EXPECT_EQ(3, std::distance(A.begin(), A.end()));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(A));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(B));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(C));
+}
+
+TEST(LazyCallGraphTest, IntraSCCEdgeRemoval) {
+ // A nice fully connected (including self-edges) SCC.
+ std::unique_ptr<Module> M1 = parseAssembly(
+ "define void @a() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG1(*M1);
+
+ // Force the graph to be fully expanded.
+ auto SCCI = CG1.postorder_scc_begin();
+ LazyCallGraph::SCC &SCC = *SCCI++;
+ EXPECT_EQ(CG1.postorder_scc_end(), SCCI);
+
+ LazyCallGraph::Node &A = *CG1.lookup(lookupFunction(*M1, "a"));
+ LazyCallGraph::Node &B = *CG1.lookup(lookupFunction(*M1, "b"));
+ LazyCallGraph::Node &C = *CG1.lookup(lookupFunction(*M1, "c"));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(A));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(B));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(C));
+
+ // Remove the edge from b -> a, which should leave the 3 functions still in
+ // a single connected component because of a -> b -> c -> a.
+ SmallVector<LazyCallGraph::SCC *, 1> NewSCCs = SCC.removeIntraSCCEdge(B, A);
+ EXPECT_EQ(0u, NewSCCs.size());
+ EXPECT_EQ(&SCC, CG1.lookupSCC(A));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(B));
+ EXPECT_EQ(&SCC, CG1.lookupSCC(C));
+
+ // Remove the edge from c -> a, which should leave 'a' in the original SCC
+ // and form a new SCC for 'b' and 'c'.
+ NewSCCs = SCC.removeIntraSCCEdge(C, A);
+ EXPECT_EQ(1u, NewSCCs.size());
+ EXPECT_EQ(&SCC, CG1.lookupSCC(A));
+ EXPECT_EQ(1, std::distance(SCC.begin(), SCC.end()));
+ LazyCallGraph::SCC *SCC2 = CG1.lookupSCC(B);
+ EXPECT_EQ(SCC2, CG1.lookupSCC(C));
+ EXPECT_EQ(SCC2, NewSCCs[0]);
+}
+
+}
diff --git a/unittests/Analysis/MixedTBAATest.cpp b/unittests/Analysis/MixedTBAATest.cpp
new file mode 100644
index 000000000000..142e04789d43
--- /dev/null
+++ b/unittests/Analysis/MixedTBAATest.cpp
@@ -0,0 +1,77 @@
+//===--- MixedTBAATest.cpp - Mixed TBAA unit tests ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Support/CommandLine.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+class MixedTBAATest : public testing::Test {
+protected:
+ MixedTBAATest() : M("MixedTBAATest", C), MD(C) {}
+
+ LLVMContext C;
+ Module M;
+ MDBuilder MD;
+ PassManager PM;
+};
+
+TEST_F(MixedTBAATest, MixedTBAA) {
+ // Setup function.
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(C),
+ std::vector<Type *>(), false);
+ auto *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ auto *BB = BasicBlock::Create(C, "entry", F);
+ auto IntType = Type::getInt32Ty(C);
+ auto PtrType = Type::getInt32PtrTy(C);
+ auto *Value = ConstantInt::get(IntType, 42);
+ auto *Addr = ConstantPointerNull::get(PtrType);
+
+ auto *Store1 = new StoreInst(Value, Addr, BB);
+ auto *Store2 = new StoreInst(Value, Addr, BB);
+ ReturnInst::Create(C, nullptr, BB);
+
+ // New TBAA metadata
+ {
+ auto RootMD = MD.createTBAARoot("Simple C/C++ TBAA");
+ auto MD1 = MD.createTBAAScalarTypeNode("omnipotent char", RootMD);
+ auto MD2 = MD.createTBAAScalarTypeNode("int", MD1);
+ auto MD3 = MD.createTBAAStructTagNode(MD2, MD2, 0);
+ Store2->setMetadata(LLVMContext::MD_tbaa, MD3);
+ }
+
+ // Old TBAA metadata
+ {
+ auto RootMD = MD.createTBAARoot("Simple C/C++ TBAA");
+ auto MD1 = MD.createTBAANode("omnipotent char", RootMD);
+ auto MD2 = MD.createTBAANode("int", MD1);
+ Store1->setMetadata(LLVMContext::MD_tbaa, MD2);
+ }
+
+ // Run the TBAA eval pass on a mixture of path-aware and non-path-aware TBAA.
+ // The order of the metadata (path-aware vs non-path-aware) is important,
+ // because the AA eval pass only runs one test per store-pair.
+ const char* args[] = { "MixedTBAATest", "-evaluate-tbaa" };
+ cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char*), args);
+ PM.add(createTypeBasedAliasAnalysisPass());
+ PM.add(createAAEvalPass());
+ PM.run(M);
+}
+
+} // end anonymous namspace
+} // end llvm namespace
+
diff --git a/unittests/Analysis/ScalarEvolutionTest.cpp b/unittests/Analysis/ScalarEvolutionTest.cpp
index 398d09e5a873..90f6997e98cd 100644
--- a/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -41,7 +41,7 @@ TEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) {
std::vector<Type *>(), false);
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
- ReturnInst::Create(Context, 0, BB);
+ ReturnInst::Create(Context, nullptr, BB);
Type *Ty = Type::getInt1Ty(Context);
Constant *Init = Constant::getNullValue(Ty);
@@ -94,7 +94,7 @@ TEST_F(ScalarEvolutionsTest, SCEVMultiplyAddRecs) {
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
- ReturnInst::Create(Context, 0, BB);
+ ReturnInst::Create(Context, nullptr, BB);
// Create a ScalarEvolution and "run" it so that it gets initialized.
PM.add(&SE);
diff --git a/unittests/Bitcode/BitReaderTest.cpp b/unittests/Bitcode/BitReaderTest.cpp
index f33af2ff474f..b6a3e9a7b75a 100644
--- a/unittests/Bitcode/BitReaderTest.cpp
+++ b/unittests/Bitcode/BitReaderTest.cpp
@@ -8,13 +8,13 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallString.h"
-#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
#include "llvm/PassManager.h"
#include "llvm/Support/MemoryBuffer.h"
#include "gtest/gtest.h"
@@ -45,7 +45,7 @@ static Module *makeLLVMModule() {
}
static void writeModuleToBuffer(SmallVectorImpl<char> &Buffer) {
- OwningPtr<Module> Mod(makeLLVMModule());
+ std::unique_ptr<Module> Mod(makeLLVMModule());
raw_svector_ostream OS(Buffer);
WriteBitcodeToFile(Mod.get(), OS);
}
@@ -54,10 +54,12 @@ TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
SmallString<1024> Mem;
writeModuleToBuffer(Mem);
MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
- std::string errMsg;
- OwningPtr<Module> m(getLazyBitcodeModule(Buffer, getGlobalContext(), &errMsg));
+ ErrorOr<Module *> ModuleOrErr =
+ getLazyBitcodeModule(Buffer, getGlobalContext());
+ std::unique_ptr<Module> m(ModuleOrErr.get());
PassManager passes;
passes.add(createVerifierPass());
+ passes.add(createDebugInfoVerifierPass());
passes.run(*m);
}
diff --git a/unittests/Bitcode/CMakeLists.txt b/unittests/Bitcode/CMakeLists.txt
index d8f5fe1f191d..743ab18ad2c7 100644
--- a/unittests/Bitcode/CMakeLists.txt
+++ b/unittests/Bitcode/CMakeLists.txt
@@ -1,6 +1,8 @@
set(LLVM_LINK_COMPONENTS
BitReader
BitWriter
+ Core
+ Support
)
add_llvm_unittest(BitcodeTests
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 52702ba23aac..65930b5e4a1b 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -1,6 +1,12 @@
add_custom_target(UnitTests)
set_target_properties(UnitTests PROPERTIES FOLDER "Tests")
+if (APPLE)
+ set(CMAKE_INSTALL_RPATH "@executable_path/../../lib")
+else(UNIX)
+ set(CMAKE_INSTALL_RPATH "\$ORIGIN/../../lib")
+endif()
+
function(add_llvm_unittest test_dirname)
add_unittest(UnitTests ${test_dirname} ${ARGN})
endfunction()
@@ -12,8 +18,9 @@ add_subdirectory(CodeGen)
add_subdirectory(DebugInfo)
add_subdirectory(ExecutionEngine)
add_subdirectory(IR)
+add_subdirectory(LineEditor)
+add_subdirectory(Linker)
add_subdirectory(MC)
-add_subdirectory(Object)
add_subdirectory(Option)
add_subdirectory(Support)
add_subdirectory(Transforms)
diff --git a/unittests/CodeGen/CMakeLists.txt b/unittests/CodeGen/CMakeLists.txt
index 5973bae3aaba..65c0ac3f20e4 100644
--- a/unittests/CodeGen/CMakeLists.txt
+++ b/unittests/CodeGen/CMakeLists.txt
@@ -1,7 +1,6 @@
set(LLVM_LINK_COMPONENTS
- asmprinter
- codegen
- support
+ AsmPrinter
+ Support
)
set(CodeGenSources
diff --git a/unittests/CodeGen/DIEHashTest.cpp b/unittests/CodeGen/DIEHashTest.cpp
index 8d8fc39a30f5..04c5a8ac0199 100644
--- a/unittests/CodeGen/DIEHashTest.cpp
+++ b/unittests/CodeGen/DIEHashTest.cpp
@@ -9,9 +9,10 @@
#include "../lib/CodeGen/AsmPrinter/DIE.h"
#include "../lib/CodeGen/AsmPrinter/DIEHash.h"
-#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
+#include "llvm/ADT/STLExtras.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -59,7 +60,7 @@ TEST(DIEHashTest, NamedType) {
TEST(DIEHashTest, NamespacedType) {
DIE CU(dwarf::DW_TAG_compile_unit);
- DIE *Space = new DIE(dwarf::DW_TAG_namespace);
+ auto Space = make_unique<DIE>(dwarf::DW_TAG_namespace);
DIEInteger One(1);
DIEString SpaceStr(&One, "space");
Space->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &SpaceStr);
@@ -67,15 +68,16 @@ TEST(DIEHashTest, NamespacedType) {
Space->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
// sibling?
- DIE *Foo = new DIE(dwarf::DW_TAG_structure_type);
+ auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
DIEString FooStr(&One, "foo");
Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
- Space->addChild(Foo);
- CU.addChild(Space);
+ DIE &N = *Foo;
+ Space->addChild(std::move(Foo));
+ CU.addChild(std::move(Space));
- uint64_t MD5Res = DIEHash().computeTypeSignature(*Foo);
+ uint64_t MD5Res = DIEHash().computeTypeSignature(N);
// The exact same hash GCC produces for this DIE.
ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
@@ -87,14 +89,6 @@ TEST(DIEHashTest, TypeWithMember) {
DIEInteger Four(4);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
- DIE *Member = new DIE(dwarf::DW_TAG_member);
- DIEString MemberStr(&Four, "member");
- Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemberStr);
- DIEInteger Zero(0);
- Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
-
- Unnamed.addChild(Member);
-
DIE Int(dwarf::DW_TAG_base_type);
DIEString IntStr(&Four, "int");
Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
@@ -102,9 +96,18 @@ TEST(DIEHashTest, TypeWithMember) {
DIEInteger Five(5);
Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
- DIEEntry IntRef(&Int);
+ DIEEntry IntRef(Int);
+
+ auto Member = make_unique<DIE>(dwarf::DW_TAG_member);
+ DIEString MemberStr(&Four, "member");
+ Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemberStr);
+ DIEInteger Zero(0);
+ Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
+ &Zero);
Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
+ Unnamed.addChild(std::move(Member));
+
uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
@@ -116,22 +119,7 @@ TEST(DIEHashTest, ReusedType) {
DIEInteger Eight(8);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIE *Mem1 = new DIE(dwarf::DW_TAG_member);
DIEInteger Four(4);
- DIEString Mem1Str(&Four, "mem1");
- Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem1Str);
- DIEInteger Zero(0);
- Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
-
- Unnamed.addChild(Mem1);
-
- DIE *Mem2 = new DIE(dwarf::DW_TAG_member);
- DIEString Mem2Str(&Four, "mem2");
- Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem2Str);
- Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Four);
-
- Unnamed.addChild(Mem2);
-
DIE Int(dwarf::DW_TAG_base_type);
DIEString IntStr(&Four, "int");
Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
@@ -139,10 +127,27 @@ TEST(DIEHashTest, ReusedType) {
DIEInteger Five(5);
Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
- DIEEntry IntRef(&Int);
+ DIEEntry IntRef(Int);
+
+ auto Mem1 = make_unique<DIE>(dwarf::DW_TAG_member);
+ DIEString Mem1Str(&Four, "mem1");
+ Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem1Str);
+ DIEInteger Zero(0);
+ Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
+ &Zero);
Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
+
+ Unnamed.addChild(std::move(Mem1));
+
+ auto Mem2 = make_unique<DIE>(dwarf::DW_TAG_member);
+ DIEString Mem2Str(&Four, "mem2");
+ Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem2Str);
+ Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
+ &Four);
Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
+ Unnamed.addChild(std::move(Mem2));
+
uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
@@ -156,14 +161,14 @@ TEST(DIEHashTest, RecursiveType) {
DIEString FooStr(&One, "foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
DIEString MemStr(&One, "mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
- DIEEntry FooRef(&Foo);
+ DIEEntry FooRef(Foo);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
// DW_AT_external and DW_AT_declaration are ignored anyway, so skip them.
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
@@ -178,7 +183,7 @@ TEST(DIEHashTest, Pointer) {
DIEString FooStr(&Eight, "foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
DIEString MemStr(&Eight, "mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEInteger Zero(0);
@@ -186,13 +191,13 @@ TEST(DIEHashTest, Pointer) {
DIE FooPtr(dwarf::DW_TAG_pointer_type);
FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIEEntry FooRef(&Foo);
+ DIEEntry FooRef(Foo);
FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
- DIEEntry FooPtrRef(&FooPtr);
+ DIEEntry FooPtrRef(FooPtr);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooPtrRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
@@ -207,7 +212,7 @@ TEST(DIEHashTest, Reference) {
DIEString FooStr(&Eight, "foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
DIEString MemStr(&Eight, "mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEInteger Zero(0);
@@ -215,17 +220,17 @@ TEST(DIEHashTest, Reference) {
DIE FooRef(dwarf::DW_TAG_reference_type);
FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIEEntry FooEntry(&Foo);
+ DIEEntry FooEntry(Foo);
FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
DIE FooRefConst(dwarf::DW_TAG_const_type);
- DIEEntry FooRefRef(&FooRef);
+ DIEEntry FooRefRef(FooRef);
FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
- DIEEntry FooRefConstRef(&FooRefConst);
+ DIEEntry FooRefConstRef(FooRefConst);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
@@ -240,7 +245,7 @@ TEST(DIEHashTest, RValueReference) {
DIEString FooStr(&Eight, "foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
DIEString MemStr(&Eight, "mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEInteger Zero(0);
@@ -248,17 +253,17 @@ TEST(DIEHashTest, RValueReference) {
DIE FooRef(dwarf::DW_TAG_rvalue_reference_type);
FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIEEntry FooEntry(&Foo);
+ DIEEntry FooEntry(Foo);
FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
DIE FooRefConst(dwarf::DW_TAG_const_type);
- DIEEntry FooRefRef(&FooRef);
+ DIEEntry FooRefRef(FooRef);
FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
- DIEEntry FooRefConstRef(&FooRefConst);
+ DIEEntry FooRefConstRef(FooRefConst);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
@@ -273,21 +278,22 @@ TEST(DIEHashTest, PtrToMember) {
DIEString FooStr(&Eight, "foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
DIEString MemStr(&Eight, "mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEInteger Zero(0);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
- DIEEntry FooEntry(&Foo);
+ DIEEntry FooEntry(Foo);
PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
- PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, &FooEntry);
+ PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
+ &FooEntry);
- DIEEntry PtrToFooMemRef(&PtrToFooMem);
+ DIEEntry PtrToFooMemRef(PtrToFooMem);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
@@ -316,22 +322,22 @@ TEST(DIEHashTest, PtrToMemberDeclDefMatch) {
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
&Zero);
DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
- DIEEntry BarEntry(&Bar);
+ DIEEntry BarEntry(Bar);
PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
- DIEEntry FooEntry(&Foo);
+ DIEEntry FooEntry(Foo);
PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
&FooEntry);
- DIEEntry PtrToFooMemRef(&PtrToFooMem);
+ DIEEntry PtrToFooMemRef(PtrToFooMem);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
MD5ResDecl = DIEHash().computeTypeSignature(Foo);
}
@@ -345,22 +351,22 @@ TEST(DIEHashTest, PtrToMemberDeclDefMatch) {
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
&Zero);
DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
- DIEEntry BarEntry(&Bar);
+ DIEEntry BarEntry(Bar);
PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
- DIEEntry FooEntry(&Foo);
+ DIEEntry FooEntry(Foo);
PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
&FooEntry);
- DIEEntry PtrToFooMemRef(&PtrToFooMem);
+ DIEEntry PtrToFooMemRef(PtrToFooMem);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
MD5ResDef = DIEHash().computeTypeSignature(Foo);
}
@@ -389,21 +395,21 @@ TEST(DIEHashTest, PtrToMemberDeclDefMisMatch) {
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
&Zero);
DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
- DIEEntry BarEntry(&Bar);
+ DIEEntry BarEntry(Bar);
PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
&BarEntry);
- DIEEntry PtrToFooMemRef(&PtrToFooMem);
+ DIEEntry PtrToFooMemRef(PtrToFooMem);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
MD5ResDecl = DIEHash().computeTypeSignature(Foo);
}
@@ -417,21 +423,21 @@ TEST(DIEHashTest, PtrToMemberDeclDefMisMatch) {
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
&Zero);
DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
- DIEEntry BarEntry(&Bar);
+ DIEEntry BarEntry(Bar);
PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
&BarEntry);
- DIEEntry PtrToFooMemRef(&PtrToFooMem);
+ DIEEntry PtrToFooMemRef(PtrToFooMem);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
MD5ResDef = DIEHash().computeTypeSignature(Foo);
}
@@ -459,37 +465,37 @@ TEST(DIEHashTest, RefUnnamedType) {
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
- DIE *Mem = new DIE(dwarf::DW_TAG_member);
+ auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
DIE UnnamedPtr(dwarf::DW_TAG_pointer_type);
UnnamedPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIEEntry UnnamedRef(&Unnamed);
+ DIEEntry UnnamedRef(Unnamed);
UnnamedPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedRef);
- DIEEntry UnnamedPtrRef(&UnnamedPtr);
+ DIEEntry UnnamedPtrRef(UnnamedPtr);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedPtrRef);
- Foo.addChild(Mem);
+ Foo.addChild(std::move(Mem));
uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
}
-// struct { struct bar { }; };
+// struct { struct foo { }; };
TEST(DIEHashTest, NestedType) {
DIE Unnamed(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
- DIE *Foo = new DIE(dwarf::DW_TAG_structure_type);
+ auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
DIEString FooStr(&One, "foo");
Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
- Unnamed.addChild(Foo);
+ Unnamed.addChild(std::move(Foo));
uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
@@ -503,15 +509,146 @@ TEST(DIEHashTest, MemberFunc) {
DIEInteger One(1);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
- DIE *Func = new DIE(dwarf::DW_TAG_subprogram);
+ auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
DIEString FuncStr(&One, "func");
Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FuncStr);
- Unnamed.addChild(Func);
+ Unnamed.addChild(std::move(Func));
uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
// The exact same hash GCC produces for this DIE.
ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res);
}
+
+// struct A {
+// static void func();
+// };
+TEST(DIEHashTest, MemberFuncFlag) {
+ DIE A(dwarf::DW_TAG_structure_type);
+ DIEInteger One(1);
+ DIEString AStr(&One, "A");
+ A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
+ A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
+ A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
+ A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
+
+ auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
+ DIEString FuncStr(&One, "func");
+ DIEString FuncLinkage(&One, "_ZN1A4funcEv");
+ DIEInteger Two(2);
+ Func->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
+ Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FuncStr);
+ Func->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
+ Func->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
+ Func->addValue(dwarf::DW_AT_linkage_name, dwarf::DW_FORM_strp, &FuncLinkage);
+ Func->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
+
+ A.addChild(std::move(Func));
+
+ uint64_t MD5Res = DIEHash().computeTypeSignature(A);
+
+ // The exact same hash GCC produces for this DIE.
+ ASSERT_EQ(0x8f78211ddce3df10ULL, MD5Res);
+}
+
+// Derived from:
+// struct A {
+// const static int PI = -3;
+// };
+// A a;
+TEST(DIEHashTest, MemberSdata) {
+ DIE A(dwarf::DW_TAG_structure_type);
+ DIEInteger One(1);
+ DIEString AStr(&One, "A");
+ A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
+ A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
+ A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
+ A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
+
+ DIEInteger Four(4);
+ DIEInteger Five(5);
+ DIEString FStr(&One, "int");
+ DIE IntTyDIE(dwarf::DW_TAG_base_type);
+ IntTyDIE.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
+ IntTyDIE.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
+ IntTyDIE.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FStr);
+
+ DIEEntry IntTy(IntTyDIE);
+ auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type);
+ PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntTy);
+
+ DIEEntry PITy(*PITyDIE);
+ auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
+ DIEString PIStr(&One, "PI");
+ DIEInteger Two(2);
+ DIEInteger NegThree(-3);
+ PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr);
+ PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
+ PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
+ PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PITy);
+ PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
+ PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
+ PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, &NegThree);
+
+ A.addChild(std::move(PI));
+
+ uint64_t MD5Res = DIEHash().computeTypeSignature(A);
+ ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res);
+}
+
+// Derived from:
+// struct A {
+// const static float PI = 3.14;
+// };
+// A a;
+TEST(DIEHashTest, MemberBlock) {
+ DIE A(dwarf::DW_TAG_structure_type);
+ DIEInteger One(1);
+ DIEString AStr(&One, "A");
+ A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
+ A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
+ A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
+ A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
+
+ DIEInteger Four(4);
+ DIEString FStr(&One, "float");
+ auto FloatTyDIE = make_unique<DIE>(dwarf::DW_TAG_base_type);
+ FloatTyDIE->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
+ FloatTyDIE->addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Four);
+ FloatTyDIE->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FStr);
+
+ DIEEntry FloatTy(*FloatTyDIE);
+ auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type);
+ PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FloatTy);
+
+ DIEEntry PITy(*PITyDIE);
+ auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
+ DIEString PIStr(&One, "PI");
+ DIEInteger Two(2);
+ PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr);
+ PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
+ PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
+ PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PITy);
+ PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
+ PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
+
+ DIEBlock PIBlock;
+ DIEInteger Blk1(0xc3);
+ DIEInteger Blk2(0xf5);
+ DIEInteger Blk3(0x48);
+ DIEInteger Blk4(0x40);
+
+ PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk1);
+ PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk2);
+ PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk3);
+ PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk4);
+
+ PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_block1, &PIBlock);
+
+ A.addChild(std::move(PI));
+
+ uint64_t MD5Res = DIEHash().computeTypeSignature(A);
+ ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res);
+}
}
diff --git a/unittests/DebugInfo/CMakeLists.txt b/unittests/DebugInfo/CMakeLists.txt
index ec580b7f69a4..e844e95251ab 100644
--- a/unittests/DebugInfo/CMakeLists.txt
+++ b/unittests/DebugInfo/CMakeLists.txt
@@ -1,7 +1,5 @@
set(LLVM_LINK_COMPONENTS
- debuginfo
- object
- support
+ DebugInfo
)
set(DebugInfoSources
diff --git a/unittests/ExecutionEngine/CMakeLists.txt b/unittests/ExecutionEngine/CMakeLists.txt
index 4eefc1e3bb1b..5e462220e5cd 100644
--- a/unittests/ExecutionEngine/CMakeLists.txt
+++ b/unittests/ExecutionEngine/CMakeLists.txt
@@ -1,14 +1,19 @@
set(LLVM_LINK_COMPONENTS
- interpreter
+ Core
+ ExecutionEngine
+ Interpreter
+ MC
+ Support
)
add_llvm_unittest(ExecutionEngineTests
ExecutionEngineTest.cpp
)
-# Include JIT/MCJIT tests only if native arch is a JIT target.
-list(FIND LLVM_TARGETS_WITH_JIT "${LLVM_NATIVE_ARCH}" have_jit)
-if (NOT have_jit EQUAL -1 )
+# Include JIT/MCJIT tests only if native arch is a built JIT target.
+list(FIND LLVM_TARGETS_TO_BUILD "${LLVM_NATIVE_ARCH}" build_idx)
+list(FIND LLVM_TARGETS_WITH_JIT "${LLVM_NATIVE_ARCH}" jit_idx)
+if (NOT build_idx LESS 0 AND NOT jit_idx LESS 0)
add_subdirectory(JIT)
add_subdirectory(MCJIT)
endif()
diff --git a/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
index 3e304e79860b..f23745c19dbb 100644
--- a/unittests/ExecutionEngine/ExecutionEngineTest.cpp
+++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Interpreter.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
@@ -27,18 +26,18 @@ protected:
}
virtual void SetUp() {
- ASSERT_TRUE(Engine.get() != NULL) << "EngineBuilder returned error: '"
+ ASSERT_TRUE(Engine.get() != nullptr) << "EngineBuilder returned error: '"
<< Error << "'";
}
GlobalVariable *NewExtGlobal(Type *T, const Twine &Name) {
return new GlobalVariable(*M, T, false, // Not constant.
- GlobalValue::ExternalLinkage, NULL, Name);
+ GlobalValue::ExternalLinkage, nullptr, Name);
}
Module *const M;
std::string Error;
- const OwningPtr<ExecutionEngine> Engine;
+ const std::unique_ptr<ExecutionEngine> Engine;
};
TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
@@ -50,14 +49,14 @@ TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
int32_t Mem2 = 4;
Engine->updateGlobalMapping(G1, &Mem2);
EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
- Engine->updateGlobalMapping(G1, NULL);
- EXPECT_EQ(NULL, Engine->getPointerToGlobalIfAvailable(G1));
+ Engine->updateGlobalMapping(G1, nullptr);
+ EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G1));
Engine->updateGlobalMapping(G1, &Mem2);
EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
GlobalVariable *G2 =
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
- EXPECT_EQ(NULL, Engine->getPointerToGlobalIfAvailable(G2))
+ EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G2))
<< "The NULL return shouldn't depend on having called"
<< " updateGlobalMapping(..., NULL)";
// Check that update...() can be called before add...().
@@ -76,7 +75,7 @@ TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
int32_t Mem2 = 4;
Engine->updateGlobalMapping(G1, &Mem2);
- EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+ EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
GlobalVariable *G2 =
@@ -84,12 +83,12 @@ TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
Engine->updateGlobalMapping(G2, &Mem1);
EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
- Engine->updateGlobalMapping(G1, NULL);
+ Engine->updateGlobalMapping(G1, nullptr);
EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1))
<< "Removing one mapping doesn't affect a different one.";
- EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem2));
+ EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem2));
Engine->updateGlobalMapping(G2, &Mem2);
- EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+ EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem2))
<< "Once a mapping is removed, we can point another GV at the"
<< " now-free address.";
@@ -105,7 +104,7 @@ TEST_F(ExecutionEngineTest, ClearModuleMappings) {
Engine->clearGlobalMappingsFromModule(M);
- EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+ EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
GlobalVariable *G2 =
NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
@@ -125,7 +124,7 @@ TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
// When the GV goes away, the ExecutionEngine should remove any
// mappings that refer to it.
G1->eraseFromParent();
- EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+ EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
}
}
diff --git a/unittests/ExecutionEngine/JIT/CMakeLists.txt b/unittests/ExecutionEngine/JIT/CMakeLists.txt
index ef37026dfc9f..5ace1c6ee48a 100644
--- a/unittests/ExecutionEngine/JIT/CMakeLists.txt
+++ b/unittests/ExecutionEngine/JIT/CMakeLists.txt
@@ -1,8 +1,12 @@
set(LLVM_LINK_COMPONENTS
- asmparser
- bitreader
- bitwriter
- jit
+ AsmParser
+ BitReader
+ BitWriter
+ Core
+ ExecutionEngine
+ JIT
+ MC
+ Support
nativecodegen
)
@@ -48,6 +52,9 @@ if(MSVC)
list(APPEND JITTestsSources JITTests.def)
endif()
+# The JIT tests need to dlopen things.
+set(LLVM_NO_DEAD_STRIP 1)
+
add_llvm_unittest(JITTests
${JITTestsSources}
)
diff --git a/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
index d3f66a27e942..db9088777a91 100644
--- a/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
@@ -83,7 +83,7 @@ public:
EXPECT_TRUE(0 != MockWrapper);
Listener.reset(JITEventListener::createIntelJITEventListener(
- MockWrapper.take()));
+ MockWrapper.release()));
EXPECT_TRUE(0 != Listener);
EE->RegisterJITEventListener(Listener.get());
}
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
index 87f482444f41..175b9fb107b8 100644
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JITEventListener.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/IR/Instructions.h"
@@ -21,8 +20,6 @@
using namespace llvm;
-int dummy;
-
namespace {
struct FunctionEmittedEvent {
@@ -71,11 +68,11 @@ class JITEventListenerTest : public testing::Test {
}
Module *M;
- const OwningPtr<ExecutionEngine> EE;
+ const std::unique_ptr<ExecutionEngine> EE;
};
// Tests on SystemZ disabled as we're running the old JIT
-#if !defined(__s390__)
+#if !defined(__s390__) && !defined(__aarch64__)
Function *buildFunction(Module *M) {
Function *Result = Function::Create(
TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
index d1c2124b9b10..61220f545f9f 100644
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
@@ -12,10 +12,10 @@
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/Config/config.h"
-#include "llvm/DIBuilder.h"
-#include "llvm/DebugInfo.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
@@ -53,8 +53,8 @@ inline const char* getFilename() {
template<typename WrapperT>
class JITEventListenerTestBase : public testing::Test {
protected:
- llvm::OwningPtr<WrapperT> MockWrapper;
- llvm::OwningPtr<llvm::JITEventListener> Listener;
+ std::unique_ptr<WrapperT> MockWrapper;
+ std::unique_ptr<llvm::JITEventListener> Listener;
public:
llvm::Module* M;
diff --git a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
index 731f7807f593..296838de61b3 100644
--- a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
@@ -9,7 +9,6 @@
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
@@ -31,27 +30,27 @@ Function *makeFakeFunction() {
// the code in the case that we don't have to allocate more memory to store the
// function bodies.
TEST(JITMemoryManagerTest, NoAllocations) {
- OwningPtr<JITMemoryManager> MemMgr(
+ std::unique_ptr<JITMemoryManager> MemMgr(
JITMemoryManager::CreateDefaultMemManager());
uintptr_t size;
std::string Error;
// Allocate the functions.
- OwningPtr<Function> F1(makeFakeFunction());
+ std::unique_ptr<Function> F1(makeFakeFunction());
size = 1024;
uint8_t *FunctionBody1 = MemMgr->startFunctionBody(F1.get(), size);
memset(FunctionBody1, 0xFF, 1024);
MemMgr->endFunctionBody(F1.get(), FunctionBody1, FunctionBody1 + 1024);
EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- OwningPtr<Function> F2(makeFakeFunction());
+ std::unique_ptr<Function> F2(makeFakeFunction());
size = 1024;
uint8_t *FunctionBody2 = MemMgr->startFunctionBody(F2.get(), size);
memset(FunctionBody2, 0xFF, 1024);
MemMgr->endFunctionBody(F2.get(), FunctionBody2, FunctionBody2 + 1024);
EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- OwningPtr<Function> F3(makeFakeFunction());
+ std::unique_ptr<Function> F3(makeFakeFunction());
size = 1024;
uint8_t *FunctionBody3 = MemMgr->startFunctionBody(F3.get(), size);
memset(FunctionBody3, 0xFF, 1024);
@@ -70,7 +69,7 @@ TEST(JITMemoryManagerTest, NoAllocations) {
// Make three large functions that take up most of the space in the slab. Then
// try allocating three smaller functions that don't require additional slabs.
TEST(JITMemoryManagerTest, TestCodeAllocation) {
- OwningPtr<JITMemoryManager> MemMgr(
+ std::unique_ptr<JITMemoryManager> MemMgr(
JITMemoryManager::CreateDefaultMemManager());
uintptr_t size;
std::string Error;
@@ -81,7 +80,7 @@ TEST(JITMemoryManagerTest, TestCodeAllocation) {
smallFuncSize * 2);
// Allocate big functions
- OwningPtr<Function> F1(makeFakeFunction());
+ std::unique_ptr<Function> F1(makeFakeFunction());
size = bigFuncSize;
uint8_t *FunctionBody1 = MemMgr->startFunctionBody(F1.get(), size);
ASSERT_LE(bigFuncSize, size);
@@ -89,7 +88,7 @@ TEST(JITMemoryManagerTest, TestCodeAllocation) {
MemMgr->endFunctionBody(F1.get(), FunctionBody1, FunctionBody1 + bigFuncSize);
EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- OwningPtr<Function> F2(makeFakeFunction());
+ std::unique_ptr<Function> F2(makeFakeFunction());
size = bigFuncSize;
uint8_t *FunctionBody2 = MemMgr->startFunctionBody(F2.get(), size);
ASSERT_LE(bigFuncSize, size);
@@ -97,7 +96,7 @@ TEST(JITMemoryManagerTest, TestCodeAllocation) {
MemMgr->endFunctionBody(F2.get(), FunctionBody2, FunctionBody2 + bigFuncSize);
EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- OwningPtr<Function> F3(makeFakeFunction());
+ std::unique_ptr<Function> F3(makeFakeFunction());
size = bigFuncSize;
uint8_t *FunctionBody3 = MemMgr->startFunctionBody(F3.get(), size);
ASSERT_LE(bigFuncSize, size);
@@ -109,7 +108,7 @@ TEST(JITMemoryManagerTest, TestCodeAllocation) {
EXPECT_EQ(3U, MemMgr->GetNumCodeSlabs());
// Allocate small functions
- OwningPtr<Function> F4(makeFakeFunction());
+ std::unique_ptr<Function> F4(makeFakeFunction());
size = smallFuncSize;
uint8_t *FunctionBody4 = MemMgr->startFunctionBody(F4.get(), size);
ASSERT_LE(smallFuncSize, size);
@@ -118,7 +117,7 @@ TEST(JITMemoryManagerTest, TestCodeAllocation) {
FunctionBody4 + smallFuncSize);
EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- OwningPtr<Function> F5(makeFakeFunction());
+ std::unique_ptr<Function> F5(makeFakeFunction());
size = smallFuncSize;
uint8_t *FunctionBody5 = MemMgr->startFunctionBody(F5.get(), size);
ASSERT_LE(smallFuncSize, size);
@@ -127,7 +126,7 @@ TEST(JITMemoryManagerTest, TestCodeAllocation) {
FunctionBody5 + smallFuncSize);
EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- OwningPtr<Function> F6(makeFakeFunction());
+ std::unique_ptr<Function> F6(makeFakeFunction());
size = smallFuncSize;
uint8_t *FunctionBody6 = MemMgr->startFunctionBody(F6.get(), size);
ASSERT_LE(smallFuncSize, size);
@@ -157,7 +156,7 @@ TEST(JITMemoryManagerTest, TestCodeAllocation) {
// Allocate five global ints of varying widths and alignment, and check their
// alignment and overlap.
TEST(JITMemoryManagerTest, TestSmallGlobalInts) {
- OwningPtr<JITMemoryManager> MemMgr(
+ std::unique_ptr<JITMemoryManager> MemMgr(
JITMemoryManager::CreateDefaultMemManager());
uint8_t *a = (uint8_t *)MemMgr->allocateGlobal(8, 0);
uint16_t *b = (uint16_t*)MemMgr->allocateGlobal(16, 2);
@@ -204,7 +203,7 @@ TEST(JITMemoryManagerTest, TestSmallGlobalInts) {
// Allocate a small global, a big global, and a third global, and make sure we
// only use two slabs for that.
TEST(JITMemoryManagerTest, TestLargeGlobalArray) {
- OwningPtr<JITMemoryManager> MemMgr(
+ std::unique_ptr<JITMemoryManager> MemMgr(
JITMemoryManager::CreateDefaultMemManager());
size_t Size = 4 * MemMgr->GetDefaultDataSlabSize();
uint64_t *a = (uint64_t*)MemMgr->allocateGlobal(64, 8);
@@ -234,7 +233,7 @@ TEST(JITMemoryManagerTest, TestLargeGlobalArray) {
// Allocate lots of medium globals so that we can test moving the bump allocator
// to a new slab.
TEST(JITMemoryManagerTest, TestManyGlobals) {
- OwningPtr<JITMemoryManager> MemMgr(
+ std::unique_ptr<JITMemoryManager> MemMgr(
JITMemoryManager::CreateDefaultMemManager());
size_t SlabSize = MemMgr->GetDefaultDataSlabSize();
size_t Size = 128;
@@ -257,7 +256,7 @@ TEST(JITMemoryManagerTest, TestManyGlobals) {
// Allocate lots of function stubs so that we can test moving the stub bump
// allocator to a new slab.
TEST(JITMemoryManagerTest, TestManyStubs) {
- OwningPtr<JITMemoryManager> MemMgr(
+ std::unique_ptr<JITMemoryManager> MemMgr(
JITMemoryManager::CreateDefaultMemManager());
size_t SlabSize = MemMgr->GetDefaultStubSlabSize();
size_t Size = 128;
@@ -268,18 +267,18 @@ TEST(JITMemoryManagerTest, TestManyStubs) {
// After allocating a bunch of stubs, we should have two.
for (int I = 0; I < Iters; ++I)
- MemMgr->allocateStub(NULL, Size, 8);
+ MemMgr->allocateStub(nullptr, Size, 8);
EXPECT_EQ(2U, MemMgr->GetNumStubSlabs());
// And after much more, we should have three.
for (int I = 0; I < Iters; ++I)
- MemMgr->allocateStub(NULL, Size, 8);
+ MemMgr->allocateStub(nullptr, Size, 8);
EXPECT_EQ(3U, MemMgr->GetNumStubSlabs());
}
// Check section allocation and alignment
TEST(JITMemoryManagerTest, AllocateSection) {
- OwningPtr<JITMemoryManager> MemMgr(
+ std::unique_ptr<JITMemoryManager> MemMgr(
JITMemoryManager::CreateDefaultMemManager());
uint8_t *code1 = MemMgr->allocateCodeSection(256, 0, 1, StringRef());
uint8_t *data1 = MemMgr->allocateDataSection(256, 16, 2, StringRef(), true);
@@ -287,10 +286,10 @@ TEST(JITMemoryManagerTest, AllocateSection) {
uint8_t *data2 = MemMgr->allocateDataSection(256, 64, 4, StringRef(), false);
uint8_t *code3 = MemMgr->allocateCodeSection(258, 64, 5, StringRef());
- EXPECT_NE((uint8_t*)0, code1);
- EXPECT_NE((uint8_t*)0, code2);
- EXPECT_NE((uint8_t*)0, data1);
- EXPECT_NE((uint8_t*)0, data2);
+ EXPECT_NE((uint8_t*)nullptr, code1);
+ EXPECT_NE((uint8_t*)nullptr, code2);
+ EXPECT_NE((uint8_t*)nullptr, data1);
+ EXPECT_NE((uint8_t*)nullptr, data2);
// Check alignment
EXPECT_EQ((uint64_t)code1 & 0xf, 0u);
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index 4c7b1e23195d..817d207c2dca 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -8,9 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Assembly/Parser.h"
+#include "llvm/AsmParser/Parser.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/IR/BasicBlock.h"
@@ -52,7 +51,8 @@ extern "C" int32_t JITTest_AvailableExternallyFunction() {
namespace {
// Tests on ARM, PowerPC and SystemZ disabled as we're running the old jit
-#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__)
+#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) \
+ && !defined(__aarch64__)
Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) {
std::vector<Type*> params;
@@ -76,7 +76,8 @@ std::string DumpFunction(const Function *F) {
}
class RecordingJITMemoryManager : public JITMemoryManager {
- const OwningPtr<JITMemoryManager> Base;
+ const std::unique_ptr<JITMemoryManager> Base;
+
public:
RecordingJITMemoryManager()
: Base(JITMemoryManager::CreateDefaultMemManager()) {
@@ -113,8 +114,8 @@ public:
return Result;
}
int stubsAllocated;
- virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
- unsigned Alignment) {
+ uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize,
+ unsigned Alignment) override {
stubsAllocated++;
return Base->allocateStub(F, StubSize, Alignment);
}
@@ -168,7 +169,7 @@ public:
bool LoadAssemblyInto(Module *M, const char *assembly) {
SMDiagnostic Error;
bool success =
- NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
+ nullptr != ParseAssemblyString(assembly, M, Error, M->getContext());
std::string errMsg;
raw_string_ostream os(errMsg);
Error.print("", os);
@@ -192,7 +193,7 @@ class JITTest : public testing::Test {
.setJITMemoryManager(RJMM)
.setErrorStr(&Error)
.setTargetOptions(Options).create());
- ASSERT_TRUE(TheJIT.get() != NULL) << Error;
+ ASSERT_TRUE(TheJIT.get() != nullptr) << Error;
}
void LoadAssembly(const char *assembly) {
@@ -202,7 +203,7 @@ class JITTest : public testing::Test {
LLVMContext Context;
Module *M; // Owned by ExecutionEngine.
RecordingJITMemoryManager *RJMM;
- OwningPtr<ExecutionEngine> TheJIT;
+ std::unique_ptr<ExecutionEngine> TheJIT;
};
// Regression test for a bug. The JIT used to allocate globals inside the same
@@ -219,13 +220,13 @@ TEST(JIT, GlobalInFunction) {
// memory is more easily tested.
MemMgr->setPoisonMemory(true);
std::string Error;
- OwningPtr<ExecutionEngine> JIT(EngineBuilder(M)
- .setEngineKind(EngineKind::JIT)
- .setErrorStr(&Error)
- .setJITMemoryManager(MemMgr)
- // The next line enables the fix:
- .setAllocateGVsWithCode(false)
- .create());
+ std::unique_ptr<ExecutionEngine> JIT(EngineBuilder(M)
+ .setEngineKind(EngineKind::JIT)
+ .setErrorStr(&Error)
+ .setJITMemoryManager(MemMgr)
+ // The next line enables the fix:
+ .setAllocateGVsWithCode(false)
+ .create());
ASSERT_EQ(Error, "");
// Create a global variable.
@@ -248,7 +249,7 @@ TEST(JIT, GlobalInFunction) {
// Since F1 was codegen'd, a pointer to G should be available.
int32_t *GPtr = (int32_t*)JIT->getPointerToGlobalIfAvailable(G);
- ASSERT_NE((int32_t*)NULL, GPtr);
+ ASSERT_NE((int32_t*)nullptr, GPtr);
EXPECT_EQ(0, *GPtr);
// F1() should increment G.
@@ -438,7 +439,7 @@ TEST_F(JITTest, ModuleDeletion) {
// too far away to call directly. This #if can probably be removed when
// http://llvm.org/PR5201 is fixed.
#if !defined(__arm__) && !defined(__mips__) && \
- !defined(__powerpc__) && !defined(__ppc__)
+ !defined(__powerpc__) && !defined(__ppc__) && !defined(__aarch64__)
typedef int (*FooPtr) ();
TEST_F(JITTest, NoStubs) {
@@ -514,7 +515,7 @@ TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
// ARM does not have an implementation of replaceMachineCodeForFunction(),
// so recompileAndRelinkFunction doesn't work.
-#if !defined(__arm__)
+#if !defined(__arm__) && !defined(__aarch64__)
TEST_F(JITTest, FunctionIsRecompiledAndRelinked) {
Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context),
GlobalValue::ExternalLinkage, "test", M);
@@ -631,22 +632,23 @@ ExecutionEngine *getJITFromBitcode(
// c_str() is null-terminated like MemoryBuffer::getMemBuffer requires.
MemoryBuffer *BitcodeBuffer =
MemoryBuffer::getMemBuffer(Bitcode, "Bitcode for test");
- std::string errMsg;
- M = getLazyBitcodeModule(BitcodeBuffer, Context, &errMsg);
- if (M == NULL) {
- ADD_FAILURE() << errMsg;
+ ErrorOr<Module*> ModuleOrErr = getLazyBitcodeModule(BitcodeBuffer, Context);
+ if (std::error_code EC = ModuleOrErr.getError()) {
+ ADD_FAILURE() << EC.message();
delete BitcodeBuffer;
- return NULL;
+ return nullptr;
}
+ M = ModuleOrErr.get();
+ std::string errMsg;
ExecutionEngine *TheJIT = EngineBuilder(M)
.setEngineKind(EngineKind::JIT)
.setErrorStr(&errMsg)
.create();
- if (TheJIT == NULL) {
+ if (TheJIT == nullptr) {
ADD_FAILURE() << errMsg;
delete M;
- M = NULL;
- return NULL;
+ M = nullptr;
+ return nullptr;
}
return TheJIT;
}
@@ -667,7 +669,8 @@ TEST(LazyLoadedJITTest, MaterializableAvailableExternallyFunctionIsntCompiled) {
"} ");
ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
Module *M;
- OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, M));
+ std::unique_ptr<ExecutionEngine> TheJIT(
+ getJITFromBitcode(Context, Bitcode, M));
ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
TheJIT->DisableLazyCompilation(true);
@@ -706,7 +709,8 @@ TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) {
"} ");
ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
Module *M;
- OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, M));
+ std::unique_ptr<ExecutionEngine> TheJIT(
+ getJITFromBitcode(Context, Bitcode, M));
ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
TheJIT->DisableLazyCompilation(true);
diff --git a/unittests/ExecutionEngine/JIT/Makefile b/unittests/ExecutionEngine/JIT/Makefile
index ef8b827a862e..d86c03bfc807 100644
--- a/unittests/ExecutionEngine/JIT/Makefile
+++ b/unittests/ExecutionEngine/JIT/Makefile
@@ -11,6 +11,9 @@ LEVEL = ../../..
TESTNAME = JIT
LINK_COMPONENTS := asmparser bitreader bitwriter jit native
+# The JIT tests need to dlopen things.
+NO_DEAD_STRIP := 1
+
include $(LEVEL)/Makefile.config
SOURCES := JITEventListenerTest.cpp JITMemoryManagerTest.cpp JITTest.cpp MultiJITTest.cpp
diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
index 4018cd5ce2f2..f530e0de5d51 100644
--- a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/Assembly/Parser.h"
+#include "llvm/AsmParser/Parser.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
@@ -21,12 +21,13 @@ using namespace llvm;
namespace {
// ARM, PowerPC and SystemZ tests disabled pending fix for PR10783.
-#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__)
+#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) \
+ && !defined(__aarch64__)
bool LoadAssemblyInto(Module *M, const char *assembly) {
SMDiagnostic Error;
bool success =
- NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
+ nullptr != ParseAssemblyString(assembly, M, Error, M->getContext());
std::string errMsg;
raw_string_ostream os(errMsg);
Error.print("", os);
@@ -70,19 +71,19 @@ void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
TEST(MultiJitTest, EagerMode) {
LLVMContext Context1;
- Module *M1 = 0;
- Function *FooF1 = 0;
+ Module *M1 = nullptr;
+ Function *FooF1 = nullptr;
createModule1(Context1, M1, FooF1);
LLVMContext Context2;
- Module *M2 = 0;
- Function *FooF2 = 0;
+ Module *M2 = nullptr;
+ Function *FooF2 = nullptr;
createModule2(Context2, M2, FooF2);
// Now we create the JIT in eager mode
- OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
EE1->DisableLazyCompilation(true);
- OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
EE2->DisableLazyCompilation(true);
// Call the `foo' function with no arguments:
@@ -100,19 +101,19 @@ TEST(MultiJitTest, EagerMode) {
TEST(MultiJitTest, LazyMode) {
LLVMContext Context1;
- Module *M1 = 0;
- Function *FooF1 = 0;
+ Module *M1 = nullptr;
+ Function *FooF1 = nullptr;
createModule1(Context1, M1, FooF1);
LLVMContext Context2;
- Module *M2 = 0;
- Function *FooF2 = 0;
+ Module *M2 = nullptr;
+ Function *FooF2 = nullptr;
createModule2(Context2, M2, FooF2);
// Now we create the JIT in lazy mode
- OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
EE1->DisableLazyCompilation(false);
- OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
EE2->DisableLazyCompilation(false);
// Call the `foo' function with no arguments:
@@ -134,18 +135,18 @@ extern "C" {
TEST(MultiJitTest, JitPool) {
LLVMContext Context1;
- Module *M1 = 0;
- Function *FooF1 = 0;
+ Module *M1 = nullptr;
+ Function *FooF1 = nullptr;
createModule1(Context1, M1, FooF1);
LLVMContext Context2;
- Module *M2 = 0;
- Function *FooF2 = 0;
+ Module *M2 = nullptr;
+ Function *FooF2 = nullptr;
createModule2(Context2, M2, FooF2);
// Now we create two JITs
- OwningPtr<ExecutionEngine> EE1(EngineBuilder(M1).create());
- OwningPtr<ExecutionEngine> EE2(EngineBuilder(M2).create());
+ std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
+ std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
Function *F1 = EE1->FindFunctionNamed("foo1");
void *foo1 = EE1->getPointerToFunction(F1);
@@ -173,6 +174,14 @@ TEST(MultiJitTest, JitPool) {
EXPECT_TRUE(fa != 0);
fa = *(intptr_t *)fa; // Bound value of IAT
}
+#elif defined(__x86_64__)
+ // getPointerToNamedFunction might be indirect jump
+ // on Win32 x64 --enable-shared.
+ // FF 25 <pcrel32>: jmp *(RIP + pointer to IAT)
+ if (sa != fa && memcmp((char *)fa, "\xFF\x25", 2) == 0) {
+ fa += *(int32_t *)(fa + 2) + 6; // Address to IAT(RIP)
+ fa = *(intptr_t *)fa; // Bound value of IAT
+ }
#endif
EXPECT_TRUE(sa == fa);
}
diff --git a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
index ed4309919387..cbd08fe9b8e2 100644
--- a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
+++ b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
@@ -1,8 +1,14 @@
set(LLVM_LINK_COMPONENTS
- asmparser
- bitreader
- bitwriter
- mcjit
+ Analysis
+ Core
+ ExecutionEngine
+ IPO
+ JIT
+ MC
+ MCJIT
+ ScalarOpts
+ Support
+ Target
nativecodegen
)
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
index 46d6d9b8a9a6..d03de898b4e6 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
@@ -13,18 +13,22 @@
//===----------------------------------------------------------------------===//
#include "llvm-c/Analysis.h"
+#include "MCJITTestAPICommon.h"
#include "llvm-c/Core.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Target.h"
+#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm-c/Transforms/Scalar.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/Host.h"
-#include "MCJITTestAPICommon.h"
#include "gtest/gtest.h"
using namespace llvm;
static bool didCallAllocateCodeSection;
+static bool didAllocateCompactUnwindSection;
+static bool didCallYield;
static uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size,
unsigned alignment,
@@ -40,6 +44,8 @@ static uint8_t *roundTripAllocateDataSection(void *object, uintptr_t size,
unsigned sectionID,
const char *sectionName,
LLVMBool isReadOnly) {
+ if (!strcmp(sectionName, "__compact_unwind"))
+ didAllocateCompactUnwindSection = true;
return static_cast<SectionMemoryManager*>(object)->allocateDataSection(
size, alignment, sectionID, sectionName, isReadOnly);
}
@@ -59,7 +65,59 @@ static void roundTripDestroy(void *object) {
delete static_cast<SectionMemoryManager*>(object);
}
+static void yield(LLVMContextRef, void *) {
+ didCallYield = true;
+}
+
namespace {
+
+// memory manager to test reserve allocation space callback
+class TestReserveAllocationSpaceMemoryManager: public SectionMemoryManager {
+public:
+ uintptr_t ReservedCodeSize;
+ uintptr_t UsedCodeSize;
+ uintptr_t ReservedDataSizeRO;
+ uintptr_t UsedDataSizeRO;
+ uintptr_t ReservedDataSizeRW;
+ uintptr_t UsedDataSizeRW;
+
+ TestReserveAllocationSpaceMemoryManager() :
+ ReservedCodeSize(0), UsedCodeSize(0), ReservedDataSizeRO(0),
+ UsedDataSizeRO(0), ReservedDataSizeRW(0), UsedDataSizeRW(0) {
+ }
+
+ virtual bool needsToReserveAllocationSpace() {
+ return true;
+ }
+
+ virtual void reserveAllocationSpace(
+ uintptr_t CodeSize, uintptr_t DataSizeRO, uintptr_t DataSizeRW) {
+ ReservedCodeSize = CodeSize;
+ ReservedDataSizeRO = DataSizeRO;
+ ReservedDataSizeRW = DataSizeRW;
+ }
+
+ void useSpace(uintptr_t* UsedSize, uintptr_t Size, unsigned Alignment) {
+ uintptr_t AlignedSize = (Size + Alignment - 1) / Alignment * Alignment;
+ uintptr_t AlignedBegin = (*UsedSize + Alignment - 1) / Alignment * Alignment;
+ *UsedSize = AlignedBegin + AlignedSize;
+ }
+
+ virtual uint8_t* allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID, StringRef SectionName, bool IsReadOnly) {
+ useSpace(IsReadOnly ? &UsedDataSizeRO : &UsedDataSizeRW, Size, Alignment);
+ return SectionMemoryManager::allocateDataSection(Size, Alignment,
+ SectionID, SectionName, IsReadOnly);
+ }
+
+ uint8_t* allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID, StringRef SectionName) {
+ useSpace(&UsedCodeSize, Size, Alignment);
+ return SectionMemoryManager::allocateCodeSection(Size, Alignment,
+ SectionID, SectionName);
+ }
+};
+
class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon {
protected:
MCJITCAPITest() {
@@ -82,14 +140,18 @@ protected:
// The operating systems below are known to be sufficiently incompatible
// that they will fail the MCJIT C API tests.
UnsupportedOSs.push_back(Triple::Cygwin);
+
+ UnsupportedEnvironments.push_back(Triple::Cygnus);
}
virtual void SetUp() {
didCallAllocateCodeSection = false;
- Module = 0;
- Function = 0;
- Engine = 0;
- Error = 0;
+ didAllocateCompactUnwindSection = false;
+ didCallYield = false;
+ Module = nullptr;
+ Function = nullptr;
+ Engine = nullptr;
+ Error = nullptr;
}
virtual void TearDown() {
@@ -104,8 +166,8 @@ protected:
LLVMSetTarget(Module, HostTriple.c_str());
- Function = LLVMAddFunction(
- Module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0));
+ Function = LLVMAddFunction(Module, "simple_function",
+ LLVMFunctionType(LLVMInt32Type(), nullptr,0, 0));
LLVMSetFunctionCallConv(Function, LLVMCCallConv);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry");
@@ -119,6 +181,84 @@ protected:
LLVMDisposeBuilder(builder);
}
+ void buildFunctionThatUsesStackmap() {
+ Module = LLVMModuleCreateWithName("simple_module");
+
+ LLVMSetTarget(Module, HostTriple.c_str());
+
+ LLVMTypeRef stackmapParamTypes[] = { LLVMInt64Type(), LLVMInt32Type() };
+ LLVMValueRef stackmap = LLVMAddFunction(
+ Module, "llvm.experimental.stackmap",
+ LLVMFunctionType(LLVMVoidType(), stackmapParamTypes, 2, 1));
+ LLVMSetLinkage(stackmap, LLVMExternalLinkage);
+
+ Function = LLVMAddFunction(Module, "simple_function",
+ LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0));
+
+ LLVMBasicBlockRef entry = LLVMAppendBasicBlock(Function, "entry");
+ LLVMBuilderRef builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, entry);
+ LLVMValueRef stackmapArgs[] = {
+ LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 5, 0),
+ LLVMConstInt(LLVMInt32Type(), 42, 0)
+ };
+ LLVMBuildCall(builder, stackmap, stackmapArgs, 3, "");
+ LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0));
+
+ LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
+ LLVMDisposeMessage(Error);
+
+ LLVMDisposeBuilder(builder);
+ }
+
+ void buildModuleWithCodeAndData() {
+ Module = LLVMModuleCreateWithName("simple_module");
+
+ LLVMSetTarget(Module, HostTriple.c_str());
+
+ // build a global int32 variable initialized to 42.
+ LLVMValueRef GlobalVar = LLVMAddGlobal(Module, LLVMInt32Type(), "intVal");
+ LLVMSetInitializer(GlobalVar, LLVMConstInt(LLVMInt32Type(), 42, 0));
+
+ {
+ Function = LLVMAddFunction(Module, "getGlobal",
+ LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0));
+ LLVMSetFunctionCallConv(Function, LLVMCCallConv);
+
+ LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function, "entry");
+ LLVMBuilderRef Builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(Builder, Entry);
+
+ LLVMValueRef IntVal = LLVMBuildLoad(Builder, GlobalVar, "intVal");
+ LLVMBuildRet(Builder, IntVal);
+
+ LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
+ LLVMDisposeMessage(Error);
+
+ LLVMDisposeBuilder(Builder);
+ }
+
+ {
+ LLVMTypeRef ParamTypes[] = { LLVMInt32Type() };
+ Function2 = LLVMAddFunction(
+ Module, "setGlobal", LLVMFunctionType(LLVMVoidType(), ParamTypes, 1, 0));
+ LLVMSetFunctionCallConv(Function2, LLVMCCallConv);
+
+ LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function2, "entry");
+ LLVMBuilderRef Builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(Builder, Entry);
+
+ LLVMValueRef Arg = LLVMGetParam(Function2, 0);
+ LLVMBuildStore(Builder, Arg, GlobalVar);
+ LLVMBuildRetVoid(Builder);
+
+ LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
+ LLVMDisposeMessage(Error);
+
+ LLVMDisposeBuilder(Builder);
+ }
+ }
+
void buildMCJITOptions() {
LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
Options.OptLevel = 2;
@@ -135,7 +275,7 @@ protected:
roundTripFinalizeMemory,
roundTripDestroy);
}
-
+
void buildMCJITEngine() {
ASSERT_EQ(
0, LLVMCreateMCJITCompilerForModule(&Engine, Module, &Options,
@@ -151,8 +291,41 @@ protected:
LLVMDisposePassManager(pass);
}
+ void buildAndRunOptPasses() {
+ LLVMPassManagerBuilderRef passBuilder;
+
+ passBuilder = LLVMPassManagerBuilderCreate();
+ LLVMPassManagerBuilderSetOptLevel(passBuilder, 2);
+ LLVMPassManagerBuilderSetSizeLevel(passBuilder, 0);
+
+ LLVMPassManagerRef functionPasses =
+ LLVMCreateFunctionPassManagerForModule(Module);
+ LLVMPassManagerRef modulePasses =
+ LLVMCreatePassManager();
+
+ LLVMAddTargetData(LLVMGetExecutionEngineTargetData(Engine), modulePasses);
+
+ LLVMPassManagerBuilderPopulateFunctionPassManager(passBuilder,
+ functionPasses);
+ LLVMPassManagerBuilderPopulateModulePassManager(passBuilder, modulePasses);
+
+ LLVMPassManagerBuilderDispose(passBuilder);
+
+ LLVMInitializeFunctionPassManager(functionPasses);
+ for (LLVMValueRef value = LLVMGetFirstFunction(Module);
+ value; value = LLVMGetNextFunction(value))
+ LLVMRunFunctionPassManager(functionPasses, value);
+ LLVMFinalizeFunctionPassManager(functionPasses);
+
+ LLVMRunPassManager(modulePasses, Module);
+
+ LLVMDisposePassManager(functionPasses);
+ LLVMDisposePassManager(modulePasses);
+ }
+
LLVMModuleRef Module;
LLVMValueRef Function;
+ LLVMValueRef Function2;
LLVMMCJITCompilerOptions Options;
LLVMExecutionEngineRef Engine;
char *Error;
@@ -194,3 +367,92 @@ TEST_F(MCJITCAPITest, custom_memory_manager) {
EXPECT_EQ(42, functionPointer.usable());
EXPECT_TRUE(didCallAllocateCodeSection);
}
+
+TEST_F(MCJITCAPITest, stackmap_creates_compact_unwind_on_darwin) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ // This test is also not supported on non-x86 platforms.
+ if (Triple(HostTriple).getArch() != Triple::x86_64)
+ return;
+
+ buildFunctionThatUsesStackmap();
+ buildMCJITOptions();
+ useRoundTripSectionMemoryManager();
+ buildMCJITEngine();
+ buildAndRunOptPasses();
+
+ union {
+ void *raw;
+ int (*usable)();
+ } functionPointer;
+ functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function);
+
+ EXPECT_EQ(42, functionPointer.usable());
+ EXPECT_TRUE(didCallAllocateCodeSection);
+
+ // Up to this point, the test is specific only to X86-64. But this next
+ // expectation is only valid on Darwin because it assumes that unwind
+ // data is made available only through compact_unwind. It would be
+ // worthwhile to extend this to handle non-Darwin platforms, in which
+ // case you'd want to look for an eh_frame or something.
+ //
+ // FIXME: Currently, MCJIT relies on a configure-time check to determine which
+ // sections to emit. The JIT client should have runtime control over this.
+ EXPECT_TRUE(
+ Triple(HostTriple).getOS() != Triple::Darwin ||
+ Triple(HostTriple).isMacOSXVersionLT(10, 7) ||
+ didAllocateCompactUnwindSection);
+}
+
+TEST_F(MCJITCAPITest, reserve_allocation_space) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ TestReserveAllocationSpaceMemoryManager* MM = new TestReserveAllocationSpaceMemoryManager();
+
+ buildModuleWithCodeAndData();
+ buildMCJITOptions();
+ Options.MCJMM = wrap(MM);
+ buildMCJITEngine();
+ buildAndRunPasses();
+
+ union {
+ void *raw;
+ int (*usable)();
+ } GetGlobalFct;
+ GetGlobalFct.raw = LLVMGetPointerToGlobal(Engine, Function);
+
+ union {
+ void *raw;
+ void (*usable)(int);
+ } SetGlobalFct;
+ SetGlobalFct.raw = LLVMGetPointerToGlobal(Engine, Function2);
+
+ SetGlobalFct.usable(789);
+ EXPECT_EQ(789, GetGlobalFct.usable());
+ EXPECT_LE(MM->UsedCodeSize, MM->ReservedCodeSize);
+ EXPECT_LE(MM->UsedDataSizeRO, MM->ReservedDataSizeRO);
+ EXPECT_LE(MM->UsedDataSizeRW, MM->ReservedDataSizeRW);
+ EXPECT_TRUE(MM->UsedCodeSize > 0);
+ EXPECT_TRUE(MM->UsedDataSizeRW > 0);
+}
+
+TEST_F(MCJITCAPITest, yield) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ buildSimpleFunction();
+ buildMCJITOptions();
+ buildMCJITEngine();
+ LLVMContextRef C = LLVMGetGlobalContext();
+ LLVMContextSetYieldCallback(C, yield, nullptr);
+ buildAndRunPasses();
+
+ union {
+ void *raw;
+ int (*usable)();
+ } functionPointer;
+ functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function);
+
+ EXPECT_EQ(42, functionPointer.usable());
+ EXPECT_TRUE(didCallYield);
+}
+
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
index c24346de84ee..98587f7e85cf 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "gtest/gtest.h"
@@ -17,17 +16,17 @@ using namespace llvm;
namespace {
TEST(MCJITMemoryManagerTest, BasicAllocations) {
- OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+ std::unique_ptr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
uint8_t *code1 = MemMgr->allocateCodeSection(256, 0, 1, "");
uint8_t *data1 = MemMgr->allocateDataSection(256, 0, 2, "", true);
uint8_t *code2 = MemMgr->allocateCodeSection(256, 0, 3, "");
uint8_t *data2 = MemMgr->allocateDataSection(256, 0, 4, "", false);
- EXPECT_NE((uint8_t*)0, code1);
- EXPECT_NE((uint8_t*)0, code2);
- EXPECT_NE((uint8_t*)0, data1);
- EXPECT_NE((uint8_t*)0, data2);
+ EXPECT_NE((uint8_t*)nullptr, code1);
+ EXPECT_NE((uint8_t*)nullptr, code2);
+ EXPECT_NE((uint8_t*)nullptr, data1);
+ EXPECT_NE((uint8_t*)nullptr, data2);
// Initialize the data
for (unsigned i = 0; i < 256; ++i) {
@@ -50,17 +49,17 @@ TEST(MCJITMemoryManagerTest, BasicAllocations) {
}
TEST(MCJITMemoryManagerTest, LargeAllocations) {
- OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+ std::unique_ptr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
uint8_t *code1 = MemMgr->allocateCodeSection(0x100000, 0, 1, "");
uint8_t *data1 = MemMgr->allocateDataSection(0x100000, 0, 2, "", true);
uint8_t *code2 = MemMgr->allocateCodeSection(0x100000, 0, 3, "");
uint8_t *data2 = MemMgr->allocateDataSection(0x100000, 0, 4, "", false);
- EXPECT_NE((uint8_t*)0, code1);
- EXPECT_NE((uint8_t*)0, code2);
- EXPECT_NE((uint8_t*)0, data1);
- EXPECT_NE((uint8_t*)0, data2);
+ EXPECT_NE((uint8_t*)nullptr, code1);
+ EXPECT_NE((uint8_t*)nullptr, code2);
+ EXPECT_NE((uint8_t*)nullptr, data1);
+ EXPECT_NE((uint8_t*)nullptr, data2);
// Initialize the data
for (unsigned i = 0; i < 0x100000; ++i) {
@@ -83,7 +82,7 @@ TEST(MCJITMemoryManagerTest, LargeAllocations) {
}
TEST(MCJITMemoryManagerTest, ManyAllocations) {
- OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+ std::unique_ptr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
uint8_t* code[10000];
uint8_t* data[10000];
@@ -99,8 +98,8 @@ TEST(MCJITMemoryManagerTest, ManyAllocations) {
data[i][j] = 2 + (i % 254);
}
- EXPECT_NE((uint8_t *)0, code[i]);
- EXPECT_NE((uint8_t *)0, data[i]);
+ EXPECT_NE((uint8_t *)nullptr, code[i]);
+ EXPECT_NE((uint8_t *)nullptr, data[i]);
}
// Verify the data (this is checking for overlaps in the addresses)
@@ -118,7 +117,7 @@ TEST(MCJITMemoryManagerTest, ManyAllocations) {
}
TEST(MCJITMemoryManagerTest, ManyVariedAllocations) {
- OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+ std::unique_ptr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
uint8_t* code[10000];
uint8_t* data[10000];
@@ -142,8 +141,8 @@ TEST(MCJITMemoryManagerTest, ManyVariedAllocations) {
data[i][j] = 2 + (i % 254);
}
- EXPECT_NE((uint8_t *)0, code[i]);
- EXPECT_NE((uint8_t *)0, data[i]);
+ EXPECT_NE((uint8_t *)nullptr, code[i]);
+ EXPECT_NE((uint8_t *)nullptr, data[i]);
uintptr_t CodeAlign = Align ? (uintptr_t)code[i] % Align : 0;
uintptr_t DataAlign = Align ? (uintptr_t)data[i] % Align : 0;
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
index 7c3239ea2598..c5ca36e417cf 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
@@ -90,12 +90,12 @@ TEST_F(MCJITMultipleModuleTest, multiple_empty_modules) {
TEST_F(MCJITMultipleModuleTest, two_module_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA, *FB;
createTwoModuleCase(A, FA, B, FB);
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
@@ -110,12 +110,12 @@ TEST_F(MCJITMultipleModuleTest, two_module_case) {
TEST_F(MCJITMultipleModuleTest, two_module_reverse_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA, *FB;
createTwoModuleCase(A, FA, B, FB);
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
@@ -131,12 +131,12 @@ TEST_F(MCJITMultipleModuleTest, two_module_reverse_case) {
TEST_F(MCJITMultipleModuleTest, two_module_extern_reverse_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA, *FB;
createTwoModuleExternCase(A, FA, B, FB);
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
@@ -152,12 +152,12 @@ TEST_F(MCJITMultipleModuleTest, two_module_extern_reverse_case) {
TEST_F(MCJITMultipleModuleTest, two_module_extern_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA, *FB;
createTwoModuleExternCase(A, FA, B, FB);
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
@@ -172,13 +172,13 @@ TEST_F(MCJITMultipleModuleTest, two_module_extern_case) {
TEST_F(MCJITMultipleModuleTest, two_module_consecutive_call_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA1, *FA2, *FB;
createTwoModuleExternCase(A, FA1, B, FB);
FA2 = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(A.get(), FA1);
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
@@ -199,7 +199,7 @@ TEST_F(MCJITMultipleModuleTest, two_module_consecutive_call_case) {
TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA, *FB;
GlobalVariable *GVA, *GVB;
A.reset(createEmptyModule("A"));
@@ -213,8 +213,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
FB = startFunction<int32_t(void)>(B.get(), "FB");
endFunctionWithRet(FB, Builder.CreateLoad(GVB));
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
@@ -237,13 +237,13 @@ TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
TEST_F(MCJITMultipleModuleTest, three_module_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B, C;
+ std::unique_ptr<Module> A, B, C;
Function *FA, *FB, *FC;
createThreeModuleCase(A, FA, B, FB, C, FC);
- createJIT(A.take());
- TheJIT->addModule(B.take());
- TheJIT->addModule(C.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
+ TheJIT->addModule(C.release());
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
checkAdd(ptr);
@@ -262,13 +262,13 @@ TEST_F(MCJITMultipleModuleTest, three_module_case) {
TEST_F(MCJITMultipleModuleTest, three_module_case_reverse_order) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B, C;
+ std::unique_ptr<Module> A, B, C;
Function *FA, *FB, *FC;
createThreeModuleCase(A, FA, B, FB, C, FC);
- createJIT(A.take());
- TheJIT->addModule(B.take());
- TheJIT->addModule(C.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
+ TheJIT->addModule(C.release());
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
@@ -287,13 +287,13 @@ TEST_F(MCJITMultipleModuleTest, three_module_case_reverse_order) {
TEST_F(MCJITMultipleModuleTest, three_module_chain_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B, C;
+ std::unique_ptr<Module> A, B, C;
Function *FA, *FB, *FC;
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
- createJIT(A.take());
- TheJIT->addModule(B.take());
- TheJIT->addModule(C.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
+ TheJIT->addModule(C.release());
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
checkAdd(ptr);
@@ -312,13 +312,13 @@ TEST_F(MCJITMultipleModuleTest, three_module_chain_case) {
TEST_F(MCJITMultipleModuleTest, three_modules_chain_case_reverse_order) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B, C;
+ std::unique_ptr<Module> A, B, C;
Function *FA, *FB, *FC;
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
- createJIT(A.take());
- TheJIT->addModule(B.take());
- TheJIT->addModule(C.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
+ TheJIT->addModule(C.release());
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
@@ -337,12 +337,12 @@ TEST_F(MCJITMultipleModuleTest, three_modules_chain_case_reverse_order) {
TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAccumulate(ptr);
@@ -358,12 +358,12 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case) {
TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case_reverse_order) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
checkAccumulate(ptr);
@@ -379,12 +379,12 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case_reverse_order) {
TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case3) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<Module> A, B;
+ std::unique_ptr<Module> A, B;
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.take());
- TheJIT->addModule(B.take());
+ createJIT(A.release());
+ TheJIT->addModule(B.release());
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
checkAccumulate(ptr);
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
index 7073a5265d62..fbbab42dbb02 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/OwningPtr.h"
+#include "MCJITTestBase.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
@@ -15,7 +15,6 @@
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
-#include "MCJITTestBase.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -49,7 +48,7 @@ public:
const MemoryBuffer* BufferFound = getObjectInternal(M);
ModulesLookedUp.insert(M->getModuleIdentifier());
if (!BufferFound)
- return NULL;
+ return nullptr;
// Our test cache wants to maintain ownership of its object buffers
// so we make a copy here for the execution engine.
return MemoryBuffer::getMemBufferCopy(BufferFound->getBuffer());
@@ -68,7 +67,7 @@ public:
const std::string ModuleID = M->getModuleIdentifier();
StringMap<const MemoryBuffer *>::iterator it = ObjMap.find(ModuleID);
if (it == ObjMap.end())
- return 0;
+ return nullptr;
return it->second;
}
@@ -101,14 +100,14 @@ protected:
void compileAndRun(int ExpectedRC = OriginalRC) {
// This function shouldn't be called until after SetUp.
- ASSERT_TRUE(TheJIT.isValid());
- ASSERT_TRUE(0 != Main);
+ ASSERT_TRUE(bool(TheJIT));
+ ASSERT_TRUE(nullptr != Main);
// We may be using a null cache, so ensure compilation is valid.
TheJIT->finalizeObject();
void *vPtr = TheJIT->getPointerToFunction(Main);
- EXPECT_TRUE(0 != vPtr)
+ EXPECT_TRUE(nullptr != vPtr)
<< "Unable to get pointer to main() from JIT";
int (*FuncPtr)(void) = (int(*)(void))(intptr_t)vPtr;
@@ -122,9 +121,9 @@ protected:
TEST_F(MCJITObjectCacheTest, SetNullObjectCache) {
SKIP_UNSUPPORTED_PLATFORM;
- createJIT(M.take());
+ createJIT(M.release());
- TheJIT->setObjectCache(NULL);
+ TheJIT->setObjectCache(nullptr);
compileAndRun();
}
@@ -133,18 +132,18 @@ TEST_F(MCJITObjectCacheTest, SetNullObjectCache) {
TEST_F(MCJITObjectCacheTest, VerifyBasicObjectCaching) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<TestObjectCache> Cache(new TestObjectCache);
+ std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
// Save a copy of the module pointer before handing it off to MCJIT.
const Module * SavedModulePointer = M.get();
- createJIT(M.take());
+ createJIT(M.release());
TheJIT->setObjectCache(Cache.get());
// Verify that our object cache does not contain the module yet.
const MemoryBuffer *ObjBuffer = Cache->getObjectInternal(SavedModulePointer);
- EXPECT_EQ(0, ObjBuffer);
+ EXPECT_EQ(nullptr, ObjBuffer);
compileAndRun();
@@ -153,7 +152,7 @@ TEST_F(MCJITObjectCacheTest, VerifyBasicObjectCaching) {
// Verify that our object cache now contains the module.
ObjBuffer = Cache->getObjectInternal(SavedModulePointer);
- EXPECT_TRUE(0 != ObjBuffer);
+ EXPECT_TRUE(nullptr != ObjBuffer);
// Verify that the cache was only notified once.
EXPECT_FALSE(Cache->wereDuplicatesInserted());
@@ -162,10 +161,10 @@ TEST_F(MCJITObjectCacheTest, VerifyBasicObjectCaching) {
TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<TestObjectCache> Cache(new TestObjectCache);
+ std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
// Compile this module with an MCJIT engine
- createJIT(M.take());
+ createJIT(M.release());
TheJIT->setObjectCache(Cache.get());
TheJIT->finalizeObject();
@@ -182,7 +181,7 @@ TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
const Module * SecondModulePointer = M.get();
// Create a new MCJIT instance to load this module then execute it.
- createJIT(M.take());
+ createJIT(M.release());
TheJIT->setObjectCache(Cache.get());
compileAndRun();
@@ -196,10 +195,10 @@ TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
SKIP_UNSUPPORTED_PLATFORM;
- OwningPtr<TestObjectCache> Cache(new TestObjectCache);
+ std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
// Compile this module with an MCJIT engine
- createJIT(M.take());
+ createJIT(M.release());
TheJIT->setObjectCache(Cache.get());
TheJIT->finalizeObject();
@@ -217,12 +216,12 @@ TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
const Module * SecondModulePointer = M.get();
// Create a new MCJIT instance to load this module then execute it.
- createJIT(M.take());
+ createJIT(M.release());
TheJIT->setObjectCache(Cache.get());
// Verify that our object cache does not contain the module yet.
const MemoryBuffer *ObjBuffer = Cache->getObjectInternal(SecondModulePointer);
- EXPECT_EQ(0, ObjBuffer);
+ EXPECT_EQ(nullptr, ObjBuffer);
// Run the function and look for the replacement return code.
compileAndRun(ReplacementRC);
@@ -232,7 +231,7 @@ TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
// Verify that our object cache now contains the module.
ObjBuffer = Cache->getObjectInternal(SecondModulePointer);
- EXPECT_TRUE(0 != ObjBuffer);
+ EXPECT_TRUE(nullptr != ObjBuffer);
// Verify that MCJIT didn't try to cache this again.
EXPECT_FALSE(Cache->wereDuplicatesInserted());
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
index fab81551fa5e..c37c1d1d599d 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
@@ -49,9 +49,9 @@ TEST_F(MCJITTest, global_variable) {
int initialValue = 5;
GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue);
- createJIT(M.take());
+ createJIT(M.release());
void *globalPtr = TheJIT->getPointerToGlobal(Global);
- EXPECT_TRUE(0 != globalPtr)
+ EXPECT_TRUE(nullptr != globalPtr)
<< "Unable to get pointer to global value from JIT";
EXPECT_EQ(initialValue, *(int32_t*)globalPtr)
@@ -62,7 +62,7 @@ TEST_F(MCJITTest, add_function) {
SKIP_UNSUPPORTED_PLATFORM;
Function *F = insertAddFunction(M.get());
- createJIT(M.take());
+ createJIT(M.release());
uint64_t addPtr = TheJIT->getFunctionAddress(F->getName().str());
EXPECT_TRUE(0 != addPtr)
<< "Unable to get pointer to function from JIT";
@@ -83,7 +83,7 @@ TEST_F(MCJITTest, run_main) {
int rc = 6;
Function *Main = insertMainFunction(M.get(), 6);
- createJIT(M.take());
+ createJIT(M.release());
uint64_t ptr = TheJIT->getFunctionAddress(Main->getName().str());
EXPECT_TRUE(0 != ptr)
<< "Unable to get pointer to main() from JIT";
@@ -104,7 +104,7 @@ TEST_F(MCJITTest, return_global) {
Value *ReadGlobal = Builder.CreateLoad(GV);
endFunctionWithRet(ReturnGlobal, ReadGlobal);
- createJIT(M.take());
+ createJIT(M.release());
uint64_t rgvPtr = TheJIT->getFunctionAddress(ReturnGlobal->getName().str());
EXPECT_TRUE(0 != rgvPtr);
@@ -175,7 +175,7 @@ TEST_F(MCJITTest, multiple_functions) {
Inner = Outer;
}
- createJIT(M.take());
+ createJIT(M.release());
uint64_t ptr = TheJIT->getFunctionAddress(Outer->getName().str());
EXPECT_TRUE(0 != ptr)
<< "Unable to get pointer to outer function from JIT";
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h b/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
index 7b6e39fb2385..a48c0713f9b8 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
@@ -71,10 +71,15 @@ protected:
/// Returns true if the host OS is known to support MCJIT
bool OSSupportsMCJIT() {
Triple Host(HostTriple);
+
+ if (std::find(UnsupportedEnvironments.begin(), UnsupportedEnvironments.end(),
+ Host.getEnvironment()) != UnsupportedEnvironments.end())
+ return false;
+
if (std::find(UnsupportedOSs.begin(), UnsupportedOSs.end(), Host.getOS())
- == UnsupportedOSs.end()) {
+ == UnsupportedOSs.end())
return true;
- }
+
return false;
}
@@ -83,6 +88,7 @@ protected:
SmallVector<Triple::ArchType, 1> HasSubArchs;
SmallVector<std::string, 2> SupportedSubArchs; // We need to own the memory
SmallVector<Triple::OSType, 4> UnsupportedOSs;
+ SmallVector<Triple::EnvironmentType, 1> UnsupportedEnvironments;
};
} // namespace llvm
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
index b42a9c0980db..25de312e0e87 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -17,6 +17,7 @@
#ifndef MCJIT_TEST_BASE_H
#define MCJIT_TEST_BASE_H
+#include "MCJITTestAPICommon.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
@@ -26,7 +27,6 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/TypeBuilder.h"
#include "llvm/Support/CodeGen.h"
-#include "MCJITTestAPICommon.h"
namespace llvm {
@@ -185,11 +185,9 @@ protected:
// Populates Modules A and B:
// Module A { Extern FB1, Function FA which calls FB1 },
// Module B { Extern FA, Function FB1, Function FB2 which calls FA },
- void createCrossModuleRecursiveCase(OwningPtr<Module> &A,
- Function *&FA,
- OwningPtr<Module> &B,
- Function *&FB1,
- Function *&FB2) {
+ void createCrossModuleRecursiveCase(std::unique_ptr<Module> &A, Function *&FA,
+ std::unique_ptr<Module> &B,
+ Function *&FB1, Function *&FB2) {
// Define FB1 in B.
B.reset(createEmptyModule("B"));
FB1 = insertAccumulateFunction(B.get(), 0, "FB1");
@@ -211,12 +209,10 @@ protected:
// Module A { Function FA },
// Module B { Extern FA, Function FB which calls FA },
// Module C { Extern FB, Function FC which calls FB },
- void createThreeModuleChainedCallsCase(OwningPtr<Module> &A,
- Function *&FA,
- OwningPtr<Module> &B,
- Function *&FB,
- OwningPtr<Module> &C,
- Function *&FC) {
+ void
+ createThreeModuleChainedCallsCase(std::unique_ptr<Module> &A, Function *&FA,
+ std::unique_ptr<Module> &B, Function *&FB,
+ std::unique_ptr<Module> &C, Function *&FC) {
A.reset(createEmptyModule("A"));
FA = insertAddFunction(A.get());
@@ -233,8 +229,8 @@ protected:
// Module A { Function FA },
// Populates Modules A and B:
// Module B { Function FB }
- void createTwoModuleCase(OwningPtr<Module> &A, Function *&FA,
- OwningPtr<Module> &B, Function *&FB) {
+ void createTwoModuleCase(std::unique_ptr<Module> &A, Function *&FA,
+ std::unique_ptr<Module> &B, Function *&FB) {
A.reset(createEmptyModule("A"));
FA = insertAddFunction(A.get());
@@ -244,8 +240,8 @@ protected:
// Module A { Function FA },
// Module B { Extern FA, Function FB which calls FA }
- void createTwoModuleExternCase(OwningPtr<Module> &A, Function *&FA,
- OwningPtr<Module> &B, Function *&FB) {
+ void createTwoModuleExternCase(std::unique_ptr<Module> &A, Function *&FA,
+ std::unique_ptr<Module> &B, Function *&FB) {
A.reset(createEmptyModule("A"));
FA = insertAddFunction(A.get());
@@ -258,12 +254,9 @@ protected:
// Module A { Function FA },
// Module B { Extern FA, Function FB which calls FA },
// Module C { Extern FB, Function FC which calls FA },
- void createThreeModuleCase(OwningPtr<Module> &A,
- Function *&FA,
- OwningPtr<Module> &B,
- Function *&FB,
- OwningPtr<Module> &C,
- Function *&FC) {
+ void createThreeModuleCase(std::unique_ptr<Module> &A, Function *&FA,
+ std::unique_ptr<Module> &B, Function *&FB,
+ std::unique_ptr<Module> &C, Function *&FC) {
A.reset(createEmptyModule("A"));
FA = insertAddFunction(A.get());
@@ -311,6 +304,8 @@ protected:
// should be kept in sync.
UnsupportedOSs.push_back(Triple::Cygwin);
UnsupportedOSs.push_back(Triple::Darwin);
+
+ UnsupportedEnvironments.push_back(Triple::Cygnus);
}
void createJIT(Module *M) {
@@ -342,10 +337,10 @@ protected:
CodeModel::Model CodeModel;
StringRef MArch;
SmallVector<std::string, 1> MAttrs;
- OwningPtr<ExecutionEngine> TheJIT;
+ std::unique_ptr<ExecutionEngine> TheJIT;
RTDyldMemoryManager *MM;
- OwningPtr<Module> M;
+ std::unique_ptr<Module> M;
};
} // namespace llvm
diff --git a/unittests/ExecutionEngine/MCJIT/Makefile b/unittests/ExecutionEngine/MCJIT/Makefile
index 33b043be9ebd..c4dd740e0575 100644
--- a/unittests/ExecutionEngine/MCJIT/Makefile
+++ b/unittests/ExecutionEngine/MCJIT/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../../..
TESTNAME = MCJIT
-LINK_COMPONENTS := core mcjit native support
+LINK_COMPONENTS := core ipo jit mcjit native support
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/IR/CMakeLists.txt b/unittests/IR/CMakeLists.txt
index fd0831f8e1fa..b439d59dec7b 100644
--- a/unittests/IR/CMakeLists.txt
+++ b/unittests/IR/CMakeLists.txt
@@ -1,15 +1,19 @@
set(LLVM_LINK_COMPONENTS
- asmparser
- core
- ipa
+ Analysis
+ AsmParser
+ Core
+ IPA
+ Support
)
set(IRSources
AttributesTest.cpp
+ ConstantRangeTest.cpp
ConstantsTest.cpp
DominatorTreeTest.cpp
IRBuilderTest.cpp
InstructionsTest.cpp
+ LeakDetectorTest.cpp
LegacyPassManagerTest.cpp
MDBuilderTest.cpp
MetadataTest.cpp
@@ -17,18 +21,14 @@ set(IRSources
PatternMatch.cpp
TypeBuilderTest.cpp
TypesTest.cpp
+ UserTest.cpp
+ ValueHandleTest.cpp
ValueMapTest.cpp
ValueTest.cpp
VerifierTest.cpp
WaymarkTest.cpp
)
-# MSVC9 and 8 cannot compile ValueMapTest.cpp due to their bug.
-# See issue#331418 in Visual Studio.
-if(MSVC AND MSVC_VERSION LESS 1600)
- list(REMOVE_ITEM IRSources ValueMapTest.cpp)
-endif()
-
# HACK: Declare a couple of source files as optionally compiled to satisfy the
# missing-file-checker in LLVM's weird CMake build.
set(LLVM_OPTIONAL_SOURCES
diff --git a/unittests/Support/ConstantRangeTest.cpp b/unittests/IR/ConstantRangeTest.cpp
index 3e0a085ed1e7..fa03302ad2bb 100644
--- a/unittests/Support/ConstantRangeTest.cpp
+++ b/unittests/IR/ConstantRangeTest.cpp
@@ -1,4 +1,4 @@
-//===- llvm/unittest/Support/ConstantRangeTest.cpp - ConstantRange tests --===//
+//===- ConstantRangeTest.cpp - ConstantRange tests ------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/ConstantRange.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Instructions.h"
#include "gtest/gtest.h"
@@ -99,11 +99,11 @@ TEST_F(ConstantRangeTest, Equality) {
}
TEST_F(ConstantRangeTest, SingleElement) {
- EXPECT_EQ(Full.getSingleElement(), static_cast<APInt *>(NULL));
- EXPECT_EQ(Empty.getSingleElement(), static_cast<APInt *>(NULL));
+ EXPECT_EQ(Full.getSingleElement(), static_cast<APInt *>(nullptr));
+ EXPECT_EQ(Empty.getSingleElement(), static_cast<APInt *>(nullptr));
EXPECT_EQ(*One.getSingleElement(), APInt(16, 0xa));
- EXPECT_EQ(Some.getSingleElement(), static_cast<APInt *>(NULL));
- EXPECT_EQ(Wrap.getSingleElement(), static_cast<APInt *>(NULL));
+ EXPECT_EQ(Some.getSingleElement(), static_cast<APInt *>(nullptr));
+ EXPECT_EQ(Wrap.getSingleElement(), static_cast<APInt *>(nullptr));
EXPECT_FALSE(Full.isSingleElement());
EXPECT_FALSE(Empty.isSingleElement());
diff --git a/unittests/IR/ConstantsTest.cpp b/unittests/IR/ConstantsTest.cpp
index fee38b891de4..0cd854998286 100644
--- a/unittests/IR/ConstantsTest.cpp
+++ b/unittests/IR/ConstantsTest.cpp
@@ -162,7 +162,7 @@ TEST(ConstantsTest, PointerCast) {
}
TEST(ConstantsTest, AsInstructionsTest) {
- OwningPtr<Module> M(new Module("MyModule", getGlobalContext()));
+ std::unique_ptr<Module> M(new Module("MyModule", getGlobalContext()));
Type *Int64Ty = Type::getInt64Ty(getGlobalContext());
Type *Int32Ty = Type::getInt32Ty(getGlobalContext());
@@ -254,6 +254,24 @@ TEST(ConstantsTest, AsInstructionsTest) {
P6STR ", i32 1");
}
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+TEST(ConstantsTest, ReplaceWithConstantTest) {
+ std::unique_ptr<Module> M(new Module("MyModule", getGlobalContext()));
+
+ Type *Int32Ty = Type::getInt32Ty(getGlobalContext());
+ Constant *One = ConstantInt::get(Int32Ty, 1);
+
+ Constant *Global =
+ M->getOrInsertGlobal("dummy", PointerType::getUnqual(Int32Ty));
+ Constant *GEP = ConstantExpr::getGetElementPtr(Global, One);
+ EXPECT_DEATH(Global->replaceAllUsesWith(GEP),
+ "this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!");
+}
+
+#endif
+#endif
+
#undef CHECK
} // end anonymous namespace
diff --git a/unittests/IR/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp
index 4e5af9395cc8..ab43d1c91fcd 100644
--- a/unittests/IR/DominatorTreeTest.cpp
+++ b/unittests/IR/DominatorTreeTest.cpp
@@ -7,8 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/Assembly/Parser.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
@@ -25,7 +26,9 @@ namespace llvm {
struct DPass : public FunctionPass {
static char ID;
virtual bool runOnFunction(Function &F) {
- DominatorTree *DT = &getAnalysis<DominatorTree>();
+ DominatorTree *DT =
+ &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ PostDominatorTree *PDT = &getAnalysis<PostDominatorTree>();
Function::iterator FI = F.begin();
BasicBlock *BB0 = FI++;
@@ -148,10 +151,34 @@ namespace llvm {
EXPECT_TRUE(DT->dominates(Y6, BB3));
+ // Post dominance.
+ EXPECT_TRUE(PDT->dominates(BB0, BB0));
+ EXPECT_FALSE(PDT->dominates(BB1, BB0));
+ EXPECT_FALSE(PDT->dominates(BB2, BB0));
+ EXPECT_FALSE(PDT->dominates(BB3, BB0));
+ EXPECT_TRUE(PDT->dominates(BB4, BB1));
+
+ // Dominance descendants.
+ SmallVector<BasicBlock *, 8> DominatedBBs, PostDominatedBBs;
+
+ DT->getDescendants(BB0, DominatedBBs);
+ PDT->getDescendants(BB0, PostDominatedBBs);
+ EXPECT_EQ(DominatedBBs.size(), 4UL);
+ EXPECT_EQ(PostDominatedBBs.size(), 1UL);
+
+ // BB3 is unreachable. It should have no dominators nor postdominators.
+ DominatedBBs.clear();
+ PostDominatedBBs.clear();
+ DT->getDescendants(BB3, DominatedBBs);
+ DT->getDescendants(BB3, PostDominatedBBs);
+ EXPECT_EQ(DominatedBBs.size(), 0UL);
+ EXPECT_EQ(PostDominatedBBs.size(), 0UL);
+
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<DominatorTree>();
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.addRequired<PostDominatorTree>();
}
DPass() : FunctionPass(ID) {
initializeDPassPass(*PassRegistry::getPassRegistry());
@@ -186,12 +213,12 @@ namespace llvm {
"}\n";
LLVMContext &C = getGlobalContext();
SMDiagnostic Err;
- return ParseAssemblyString(ModuleStrig, NULL, Err, C);
+ return ParseAssemblyString(ModuleStrig, nullptr, Err, C);
}
TEST(DominatorTree, Unreachable) {
DPass *P = new DPass();
- OwningPtr<Module> M(makeLLVMModule(P));
+ std::unique_ptr<Module> M(makeLLVMModule(P));
PassManager Passes;
Passes.add(P);
Passes.run(*M);
@@ -200,5 +227,6 @@ namespace llvm {
}
INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTree)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false)
diff --git a/unittests/IR/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp
index 2f390f7f75a2..21085755fbad 100644
--- a/unittests/IR/IRBuilderTest.cpp
+++ b/unittests/IR/IRBuilderTest.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/IRBuilder.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
@@ -16,6 +15,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/NoFolder.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -31,16 +31,16 @@ protected:
F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
BB = BasicBlock::Create(Ctx, "", F);
GV = new GlobalVariable(*M, Type::getFloatTy(Ctx), true,
- GlobalValue::ExternalLinkage, 0);
+ GlobalValue::ExternalLinkage, nullptr);
}
virtual void TearDown() {
- BB = 0;
+ BB = nullptr;
M.reset();
}
LLVMContext Ctx;
- OwningPtr<Module> M;
+ std::unique_ptr<Module> M;
Function *F;
BasicBlock *BB;
GlobalVariable *GV;
@@ -71,9 +71,9 @@ TEST_F(IRBuilderTest, Lifetime) {
IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1);
IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1);
- ASSERT_TRUE(II_Start1 != NULL);
+ ASSERT_TRUE(II_Start1 != nullptr);
EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start);
- ASSERT_TRUE(II_End1 != NULL);
+ ASSERT_TRUE(II_End1 != nullptr);
EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end);
}
@@ -107,6 +107,14 @@ TEST_F(IRBuilderTest, LandingPadName) {
EXPECT_EQ(LP->getName(), "LP");
}
+TEST_F(IRBuilderTest, DataLayout) {
+ std::unique_ptr<Module> M(new Module("test", Ctx));
+ M->setDataLayout("e-n32");
+ EXPECT_TRUE(M->getDataLayout()->isLegalInteger(32));
+ M->setDataLayout("e");
+ EXPECT_FALSE(M->getDataLayout()->isLegalInteger(32));
+}
+
TEST_F(IRBuilderTest, GetIntTy) {
IRBuilder<> Builder(BB);
IntegerType *Ty1 = Builder.getInt1Ty();
@@ -147,6 +155,13 @@ TEST_F(IRBuilderTest, FastMathFlags) {
FAdd = cast<Instruction>(F);
EXPECT_TRUE(FAdd->hasNoNaNs());
+ // Now, try it with CreateBinOp
+ F = Builder.CreateBinOp(Instruction::FAdd, F, F);
+ EXPECT_TRUE(Builder.getFastMathFlags().any());
+ ASSERT_TRUE(isa<Instruction>(F));
+ FAdd = cast<Instruction>(F);
+ EXPECT_TRUE(FAdd->hasNoNaNs());
+
F = Builder.CreateFDiv(F, F);
EXPECT_TRUE(Builder.getFastMathFlags().any());
EXPECT_TRUE(Builder.getFastMathFlags().UnsafeAlgebra);
@@ -183,6 +198,56 @@ TEST_F(IRBuilderTest, FastMathFlags) {
}
+TEST_F(IRBuilderTest, WrapFlags) {
+ IRBuilder<true, NoFolder> Builder(BB);
+
+ // Test instructions.
+ GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true,
+ GlobalValue::ExternalLinkage, nullptr);
+ Value *V = Builder.CreateLoad(G);
+ EXPECT_TRUE(
+ cast<BinaryOperator>(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap());
+ EXPECT_TRUE(
+ cast<BinaryOperator>(Builder.CreateNSWMul(V, V))->hasNoSignedWrap());
+ EXPECT_TRUE(
+ cast<BinaryOperator>(Builder.CreateNSWSub(V, V))->hasNoSignedWrap());
+ EXPECT_TRUE(cast<BinaryOperator>(
+ Builder.CreateShl(V, V, "", /* NUW */ false, /* NSW */ true))
+ ->hasNoSignedWrap());
+
+ EXPECT_TRUE(
+ cast<BinaryOperator>(Builder.CreateNUWAdd(V, V))->hasNoUnsignedWrap());
+ EXPECT_TRUE(
+ cast<BinaryOperator>(Builder.CreateNUWMul(V, V))->hasNoUnsignedWrap());
+ EXPECT_TRUE(
+ cast<BinaryOperator>(Builder.CreateNUWSub(V, V))->hasNoUnsignedWrap());
+ EXPECT_TRUE(cast<BinaryOperator>(
+ Builder.CreateShl(V, V, "", /* NUW */ true, /* NSW */ false))
+ ->hasNoUnsignedWrap());
+
+ // Test operators created with constants.
+ Constant *C = Builder.getInt32(42);
+ EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWAdd(C, C))
+ ->hasNoSignedWrap());
+ EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWSub(C, C))
+ ->hasNoSignedWrap());
+ EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWMul(C, C))
+ ->hasNoSignedWrap());
+ EXPECT_TRUE(cast<OverflowingBinaryOperator>(
+ Builder.CreateShl(C, C, "", /* NUW */ false, /* NSW */ true))
+ ->hasNoSignedWrap());
+
+ EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWAdd(C, C))
+ ->hasNoUnsignedWrap());
+ EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWSub(C, C))
+ ->hasNoUnsignedWrap());
+ EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWMul(C, C))
+ ->hasNoUnsignedWrap());
+ EXPECT_TRUE(cast<OverflowingBinaryOperator>(
+ Builder.CreateShl(C, C, "", /* NUW */ true, /* NSW */ false))
+ ->hasNoUnsignedWrap());
+}
+
TEST_F(IRBuilderTest, RAIIHelpersTest) {
IRBuilder<> Builder(BB);
EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
diff --git a/unittests/IR/InstructionsTest.cpp b/unittests/IR/InstructionsTest.cpp
index 65f85ba1b707..7ec9b62207fb 100644
--- a/unittests/IR/InstructionsTest.cpp
+++ b/unittests/IR/InstructionsTest.cpp
@@ -14,11 +14,14 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "gtest/gtest.h"
+#include <memory>
namespace llvm {
namespace {
@@ -47,6 +50,58 @@ TEST(InstructionsTest, ReturnInst) {
delete r1;
}
+// Test fixture that provides a module and a single function within it. Useful
+// for tests that need to refer to the function in some way.
+class ModuleWithFunctionTest : public testing::Test {
+protected:
+ ModuleWithFunctionTest() : M(new Module("MyModule", Ctx)) {
+ FArgTypes.push_back(Type::getInt8Ty(Ctx));
+ FArgTypes.push_back(Type::getInt32Ty(Ctx));
+ FArgTypes.push_back(Type::getInt64Ty(Ctx));
+ FunctionType *FTy =
+ FunctionType::get(Type::getVoidTy(Ctx), FArgTypes, false);
+ F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
+ }
+
+ LLVMContext Ctx;
+ std::unique_ptr<Module> M;
+ SmallVector<Type *, 3> FArgTypes;
+ Function *F;
+};
+
+TEST_F(ModuleWithFunctionTest, CallInst) {
+ Value *Args[] = {ConstantInt::get(Type::getInt8Ty(Ctx), 20),
+ ConstantInt::get(Type::getInt32Ty(Ctx), 9999),
+ ConstantInt::get(Type::getInt64Ty(Ctx), 42)};
+ std::unique_ptr<CallInst> Call(CallInst::Create(F, Args));
+
+ // Make sure iteration over a call's arguments works as expected.
+ unsigned Idx = 0;
+ for (Value *Arg : Call->arg_operands()) {
+ EXPECT_EQ(FArgTypes[Idx], Arg->getType());
+ EXPECT_EQ(Call->getArgOperand(Idx)->getType(), Arg->getType());
+ Idx++;
+ }
+}
+
+TEST_F(ModuleWithFunctionTest, InvokeInst) {
+ BasicBlock *BB1 = BasicBlock::Create(Ctx, "", F);
+ BasicBlock *BB2 = BasicBlock::Create(Ctx, "", F);
+
+ Value *Args[] = {ConstantInt::get(Type::getInt8Ty(Ctx), 20),
+ ConstantInt::get(Type::getInt32Ty(Ctx), 9999),
+ ConstantInt::get(Type::getInt64Ty(Ctx), 42)};
+ std::unique_ptr<InvokeInst> Invoke(InvokeInst::Create(F, BB1, BB2, Args));
+
+ // Make sure iteration over invoke's arguments works as expected.
+ unsigned Idx = 0;
+ for (Value *Arg : Invoke->arg_operands()) {
+ EXPECT_EQ(FArgTypes[Idx], Arg->getType());
+ EXPECT_EQ(Invoke->getArgOperand(Idx)->getType(), Arg->getType());
+ Idx++;
+ }
+}
+
TEST(InstructionsTest, BranchInst) {
LLVMContext &C(getGlobalContext());
@@ -65,9 +120,9 @@ TEST(InstructionsTest, BranchInst) {
EXPECT_EQ(1U, b0->getNumOperands());
EXPECT_NE(b0->op_begin(), b0->op_end());
- EXPECT_EQ(b0->op_end(), llvm::next(b0->op_begin()));
+ EXPECT_EQ(b0->op_end(), std::next(b0->op_begin()));
- EXPECT_EQ(b0->op_end(), llvm::next(b0->op_begin()));
+ EXPECT_EQ(b0->op_end(), std::next(b0->op_begin()));
IntegerType* Int1 = IntegerType::get(C, 1);
Constant* One = ConstantInt::get(Int1, 1, true);
@@ -145,6 +200,7 @@ TEST(InstructionsTest, CastInst) {
Type *V2Int64PtrTy = VectorType::get(Int64PtrTy, 2);
Type *V2Int32PtrTy = VectorType::get(Int32PtrTy, 2);
+ Type *V4Int32PtrTy = VectorType::get(Int32PtrTy, 4);
const Constant* c8 = Constant::getNullValue(V8x8Ty);
const Constant* c64 = Constant::getNullValue(V8x64Ty);
@@ -205,6 +261,21 @@ TEST(InstructionsTest, CastInst) {
EXPECT_FALSE(CastInst::isBitCastable(V2Int64Ty, V2Int32Ty));
+ EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,
+ Constant::getNullValue(V4Int32PtrTy),
+ V2Int32PtrTy));
+ EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,
+ Constant::getNullValue(V2Int32PtrTy),
+ V4Int32PtrTy));
+
+ EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,
+ Constant::getNullValue(V4Int32PtrAS1Ty),
+ V2Int32PtrTy));
+ EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,
+ Constant::getNullValue(V2Int32PtrTy),
+ V4Int32PtrAS1Ty));
+
+
// Check that assertion is not hit when creating a cast with a vector of
// pointers
// First form
@@ -269,7 +340,7 @@ TEST(InstructionsTest, VectorGep) {
int64_t Offset;
DataLayout TD("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3"
- "2:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80"
+ "2:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-s:64:64-f80"
":128:128-n8:16:32:64-S128");
// Make sure we don't crash
GetPointerBaseWithConstantOffset(Gep0, Offset, &TD);
@@ -344,7 +415,7 @@ TEST(InstructionsTest, isEliminableCastPair) {
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
CastInst::IntToPtr,
Int64PtrTy, Int64Ty, Int64PtrTy,
- Int32Ty, 0, Int32Ty),
+ Int32Ty, nullptr, Int32Ty),
CastInst::BitCast);
// Source and destination have unknown sizes, but the same address space and
@@ -352,7 +423,7 @@ TEST(InstructionsTest, isEliminableCastPair) {
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
CastInst::IntToPtr,
Int64PtrTy, Int64Ty, Int64PtrTy,
- 0, 0, 0),
+ nullptr, nullptr, nullptr),
CastInst::BitCast);
// Source and destination have unknown sizes, but the same address space and
@@ -360,28 +431,28 @@ TEST(InstructionsTest, isEliminableCastPair) {
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
CastInst::IntToPtr,
Int64PtrTy, Int32Ty, Int64PtrTy,
- 0, 0, 0),
+ nullptr, nullptr, nullptr),
0U);
// Middle pointer big enough -> bitcast.
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
CastInst::PtrToInt,
Int64Ty, Int64PtrTy, Int64Ty,
- 0, Int64Ty, 0),
+ nullptr, Int64Ty, nullptr),
CastInst::BitCast);
// Middle pointer too small -> fail.
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
CastInst::PtrToInt,
Int64Ty, Int64PtrTy, Int64Ty,
- 0, Int32Ty, 0),
+ nullptr, Int32Ty, nullptr),
0U);
// Test that we don't eliminate bitcasts between different address spaces,
// or if we don't have available pointer size information.
DataLayout DL("e-p:32:32:32-p1:16:16:16-p2:64:64:64-i1:8:8-i8:8:8-i16:16:16"
"-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64"
- "-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128");
+ "-v128:128:128-a:0:64-s:64:64-f80:128:128-n8:16:32:64-S128");
Type* Int64PtrTyAS1 = Type::getInt64PtrTy(C, 1);
Type* Int64PtrTyAS2 = Type::getInt64PtrTy(C, 2);
@@ -393,25 +464,58 @@ TEST(InstructionsTest, isEliminableCastPair) {
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
CastInst::AddrSpaceCast,
Int16Ty, Int64PtrTyAS1, Int64PtrTyAS2,
- 0, Int16SizePtr, Int64SizePtr),
+ nullptr, Int16SizePtr, Int64SizePtr),
0U);
// Cannot simplify addrspacecast, ptrtoint
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::AddrSpaceCast,
CastInst::PtrToInt,
Int64PtrTyAS1, Int64PtrTyAS2, Int16Ty,
- Int64SizePtr, Int16SizePtr, 0),
+ Int64SizePtr, Int16SizePtr, nullptr),
0U);
// Pass since the bitcast address spaces are the same
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
CastInst::BitCast,
Int16Ty, Int64PtrTyAS1, Int64PtrTyAS1,
- 0, 0, 0),
+ nullptr, nullptr, nullptr),
CastInst::IntToPtr);
}
+TEST(InstructionsTest, CloneCall) {
+ LLVMContext &C(getGlobalContext());
+ Type *Int32Ty = Type::getInt32Ty(C);
+ Type *ArgTys[] = {Int32Ty, Int32Ty, Int32Ty};
+ Type *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false);
+ Value *Callee = Constant::getNullValue(FnTy->getPointerTo());
+ Value *Args[] = {
+ ConstantInt::get(Int32Ty, 1),
+ ConstantInt::get(Int32Ty, 2),
+ ConstantInt::get(Int32Ty, 3)
+ };
+ std::unique_ptr<CallInst> Call(CallInst::Create(Callee, Args, "result"));
+
+ // Test cloning the tail call kind.
+ CallInst::TailCallKind Kinds[] = {CallInst::TCK_None, CallInst::TCK_Tail,
+ CallInst::TCK_MustTail};
+ for (CallInst::TailCallKind TCK : Kinds) {
+ Call->setTailCallKind(TCK);
+ std::unique_ptr<CallInst> Clone(cast<CallInst>(Call->clone()));
+ EXPECT_EQ(Call->getTailCallKind(), Clone->getTailCallKind());
+ }
+ Call->setTailCallKind(CallInst::TCK_None);
+
+ // Test cloning an attribute.
+ {
+ AttrBuilder AB;
+ AB.addAttribute(Attribute::ReadOnly);
+ Call->setAttributes(AttributeSet::get(C, AttributeSet::FunctionIndex, AB));
+ std::unique_ptr<CallInst> Clone(cast<CallInst>(Call->clone()));
+ EXPECT_TRUE(Clone->onlyReadsMemory());
+ }
+}
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/unittests/Support/LeakDetectorTest.cpp b/unittests/IR/LeakDetectorTest.cpp
index d198c7a8bda0..94eed4c1432b 100644
--- a/unittests/Support/LeakDetectorTest.cpp
+++ b/unittests/IR/LeakDetectorTest.cpp
@@ -1,4 +1,4 @@
-//===- llvm/unittest/LeakDetector/LeakDetector.cpp - LeakDetector tests ---===//
+//===- LeakDetectorTest.cpp -----------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/IR/LeakDetector.h"
#include "gtest/gtest.h"
-#include "llvm/Support/LeakDetector.h"
using namespace llvm;
diff --git a/unittests/IR/LegacyPassManagerTest.cpp b/unittests/IR/LegacyPassManagerTest.cpp
index 11841bdeac0d..9c2a835ca099 100644
--- a/unittests/IR/LegacyPassManagerTest.cpp
+++ b/unittests/IR/LegacyPassManagerTest.cpp
@@ -19,8 +19,6 @@
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
@@ -28,10 +26,12 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
#include "llvm/Pass.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
@@ -99,7 +99,7 @@ namespace llvm {
initializeModuleNDMPass(*PassRegistry::getPassRegistry());
}
virtual bool runOnModule(Module &M) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run++;
return false;
}
@@ -176,7 +176,7 @@ namespace llvm {
initializeCGPassPass(*PassRegistry::getPassRegistry());
}
virtual bool runOnSCC(CallGraphSCC &SCMM) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
}
@@ -215,7 +215,7 @@ namespace llvm {
return false;
}
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
}
@@ -252,7 +252,7 @@ namespace llvm {
return false;
}
virtual bool runOnBasicBlock(BasicBlock &BB) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
}
@@ -277,7 +277,7 @@ namespace llvm {
initializeFPassPass(*PassRegistry::getPassRegistry());
}
virtual bool runOnModule(Module &M) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) {
Function &F = *I;
{
@@ -303,7 +303,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
PassManager Passes;
- Passes.add(new DataLayout(&M));
+ Passes.add(new DataLayoutPass(&M));
Passes.add(mNDM2);
Passes.add(mNDM);
Passes.add(mNDNM);
@@ -327,7 +327,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
PassManager Passes;
- Passes.add(new DataLayout(&M));
+ Passes.add(new DataLayoutPass(&M));
Passes.add(mNDM);
Passes.add(mNDNM);
Passes.add(mNDM2);// invalidates mNDM needed by mDNM
@@ -346,10 +346,10 @@ namespace llvm {
template<typename T>
void MemoryTestHelper(int run) {
- OwningPtr<Module> M(makeLLVMModule());
+ std::unique_ptr<Module> M(makeLLVMModule());
T *P = new T();
PassManager Passes;
- Passes.add(new DataLayout(M.get()));
+ Passes.add(new DataLayoutPass(M.get()));
Passes.add(P);
Passes.run(*M);
T::finishedOK(run);
@@ -360,7 +360,7 @@ namespace llvm {
Module *M = makeLLVMModule();
T *P = new T();
PassManager Passes;
- Passes.add(new DataLayout(M));
+ Passes.add(new DataLayoutPass(M));
Passes.add(P);
Passes.run(*M);
T::finishedOK(run, N);
@@ -398,7 +398,7 @@ namespace llvm {
SCOPED_TRACE("Running OnTheFlyTest");
struct OnTheFlyTest *O = new OnTheFlyTest();
PassManager Passes;
- Passes.add(new DataLayout(M));
+ Passes.add(new DataLayoutPass(M));
Passes.add(O);
Passes.run(*M);
@@ -412,7 +412,7 @@ namespace llvm {
Module* mod = new Module("test-mem", getGlobalContext());
mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
- "a0:0:64-s0:64:64-f80:128:128");
+ "a:0:64-s:64:64-f80:128:128");
mod->setTargetTriple("x86_64-unknown-linux-gnu");
// Type Definitions
@@ -476,7 +476,7 @@ namespace llvm {
// Function: test1 (func_test1)
{
- BasicBlock* label_entry = BasicBlock::Create(getGlobalContext(), "entry",func_test1,0);
+ BasicBlock* label_entry = BasicBlock::Create(getGlobalContext(), "entry",func_test1,nullptr);
// Block entry (label_entry)
CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry);
@@ -491,7 +491,7 @@ namespace llvm {
// Function: test2 (func_test2)
{
- BasicBlock* label_entry_5 = BasicBlock::Create(getGlobalContext(), "entry",func_test2,0);
+ BasicBlock* label_entry_5 = BasicBlock::Create(getGlobalContext(), "entry",func_test2,nullptr);
// Block entry (label_entry_5)
CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5);
@@ -506,7 +506,7 @@ namespace llvm {
// Function: test3 (func_test3)
{
- BasicBlock* label_entry_8 = BasicBlock::Create(getGlobalContext(), "entry",func_test3,0);
+ BasicBlock* label_entry_8 = BasicBlock::Create(getGlobalContext(), "entry",func_test3,nullptr);
// Block entry (label_entry_8)
CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8);
@@ -524,10 +524,10 @@ namespace llvm {
Value* int1_f = args++;
int1_f->setName("f");
- BasicBlock* label_entry_11 = BasicBlock::Create(getGlobalContext(), "entry",func_test4,0);
- BasicBlock* label_bb = BasicBlock::Create(getGlobalContext(), "bb",func_test4,0);
- BasicBlock* label_bb1 = BasicBlock::Create(getGlobalContext(), "bb1",func_test4,0);
- BasicBlock* label_return = BasicBlock::Create(getGlobalContext(), "return",func_test4,0);
+ BasicBlock* label_entry_11 = BasicBlock::Create(getGlobalContext(), "entry",func_test4,nullptr);
+ BasicBlock* label_bb = BasicBlock::Create(getGlobalContext(), "bb",func_test4,nullptr);
+ BasicBlock* label_bb1 = BasicBlock::Create(getGlobalContext(), "bb1",func_test4,nullptr);
+ BasicBlock* label_return = BasicBlock::Create(getGlobalContext(), "return",func_test4,nullptr);
// Block entry (label_entry_11)
BranchInst::Create(label_bb, label_entry_11);
@@ -550,7 +550,7 @@ namespace llvm {
INITIALIZE_PASS(ModuleNDM, "mndm", "mndm", false, false)
INITIALIZE_PASS_BEGIN(CGPass, "cgp","cgp", false, false)
-INITIALIZE_PASS_DEPENDENCY(CallGraph)
+INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
INITIALIZE_PASS_END(CGPass, "cgp","cgp", false, false)
INITIALIZE_PASS(FPass, "fp","fp", false, false)
INITIALIZE_PASS_BEGIN(LPass, "lp","lp", false, false)
diff --git a/unittests/IR/MDBuilderTest.cpp b/unittests/IR/MDBuilderTest.cpp
index 665d559bf0b7..fc4674ea1357 100644
--- a/unittests/IR/MDBuilderTest.cpp
+++ b/unittests/IR/MDBuilderTest.cpp
@@ -9,6 +9,7 @@
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/IR/Operator.h"
#include "gtest/gtest.h"
@@ -32,8 +33,8 @@ TEST_F(MDBuilderTest, createFPMath) {
MDBuilder MDHelper(Context);
MDNode *MD0 = MDHelper.createFPMath(0.0);
MDNode *MD1 = MDHelper.createFPMath(1.0);
- EXPECT_EQ(MD0, (MDNode *)0);
- EXPECT_NE(MD1, (MDNode *)0);
+ EXPECT_EQ(MD0, (MDNode *)nullptr);
+ EXPECT_NE(MD1, (MDNode *)nullptr);
EXPECT_EQ(MD1->getNumOperands(), 1U);
Value *Op = MD1->getOperand(0);
EXPECT_TRUE(isa<ConstantFP>(Op));
@@ -46,8 +47,8 @@ TEST_F(MDBuilderTest, createRangeMetadata) {
APInt A(8, 1), B(8, 2);
MDNode *R0 = MDHelper.createRange(A, A);
MDNode *R1 = MDHelper.createRange(A, B);
- EXPECT_EQ(R0, (MDNode *)0);
- EXPECT_NE(R1, (MDNode *)0);
+ EXPECT_EQ(R0, (MDNode *)nullptr);
+ EXPECT_NE(R1, (MDNode *)nullptr);
EXPECT_EQ(R1->getNumOperands(), 2U);
EXPECT_TRUE(isa<ConstantInt>(R1->getOperand(0)));
EXPECT_TRUE(isa<ConstantInt>(R1->getOperand(1)));
@@ -65,8 +66,8 @@ TEST_F(MDBuilderTest, createAnonymousTBAARoot) {
EXPECT_GE(R1->getNumOperands(), 1U);
EXPECT_EQ(R0->getOperand(0), R0);
EXPECT_EQ(R1->getOperand(0), R1);
- EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == 0);
- EXPECT_TRUE(R1->getNumOperands() == 1 || R1->getOperand(1) == 0);
+ EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == nullptr);
+ EXPECT_TRUE(R1->getNumOperands() == 1 || R1->getOperand(1) == nullptr);
}
TEST_F(MDBuilderTest, createTBAARoot) {
MDBuilder MDHelper(Context);
@@ -76,7 +77,7 @@ TEST_F(MDBuilderTest, createTBAARoot) {
EXPECT_GE(R0->getNumOperands(), 1U);
EXPECT_TRUE(isa<MDString>(R0->getOperand(0)));
EXPECT_EQ(cast<MDString>(R0->getOperand(0))->getString(), "Root");
- EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == 0);
+ EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == nullptr);
}
TEST_F(MDBuilderTest, createTBAANode) {
MDBuilder MDHelper(Context);
diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp
index 352e83ee662e..4f7bd720d1c3 100644
--- a/unittests/IR/MetadataTest.cpp
+++ b/unittests/IR/MetadataTest.cpp
@@ -13,7 +13,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -103,7 +103,7 @@ TEST_F(MDNodeTest, Simple) {
#endif
EXPECT_EQ(n4, n1);
EXPECT_EQ(n5, n2);
- EXPECT_EQ(n6, (Value*)0);
+ EXPECT_EQ(n6, (Value*)nullptr);
EXPECT_EQ(3u, n1->getNumOperands());
EXPECT_EQ(s1, n1->getOperand(0));
diff --git a/unittests/IR/PassManagerTest.cpp b/unittests/IR/PassManagerTest.cpp
index 7b60e3899a0e..25037a773cfc 100644
--- a/unittests/IR/PassManagerTest.cpp
+++ b/unittests/IR/PassManagerTest.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Assembly/Parser.h"
+#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
@@ -19,21 +19,21 @@ using namespace llvm;
namespace {
-class TestAnalysisPass {
+class TestFunctionAnalysis {
public:
- typedef Function IRUnitT;
-
struct Result {
Result(int Count) : InstructionCount(Count) {}
- bool invalidate(Function *) { return true; }
int InstructionCount;
};
/// \brief Returns an opaque, unique ID for this pass type.
static void *ID() { return (void *)&PassID; }
+ TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
+
/// \brief Run the analysis pass over the function and return a result.
- Result run(Function *F) {
+ Result run(Function *F, FunctionAnalysisManager *AM) {
+ ++Runs;
int Count = 0;
for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI)
for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
@@ -45,49 +45,135 @@ public:
private:
/// \brief Private static data to provide unique ID.
static char PassID;
+
+ int &Runs;
};
-char TestAnalysisPass::PassID;
+char TestFunctionAnalysis::PassID;
+
+class TestModuleAnalysis {
+public:
+ struct Result {
+ Result(int Count) : FunctionCount(Count) {}
+ int FunctionCount;
+ };
+
+ static void *ID() { return (void *)&PassID; }
+
+ TestModuleAnalysis(int &Runs) : Runs(Runs) {}
+
+ Result run(Module *M, ModuleAnalysisManager *AM) {
+ ++Runs;
+ int Count = 0;
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ ++Count;
+ return Result(Count);
+ }
+
+private:
+ static char PassID;
+
+ int &Runs;
+};
+
+char TestModuleAnalysis::PassID;
struct TestModulePass {
TestModulePass(int &RunCount) : RunCount(RunCount) {}
- bool run(Module *M) {
+ PreservedAnalyses run(Module *M) {
++RunCount;
- return true;
+ return PreservedAnalyses::none();
}
+ static StringRef name() { return "TestModulePass"; }
+
int &RunCount;
};
-struct TestFunctionPass {
- TestFunctionPass(AnalysisManager &AM, int &RunCount, int &AnalyzedInstrCount)
- : AM(AM), RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {
+struct TestPreservingModulePass {
+ PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); }
+
+ static StringRef name() { return "TestPreservingModulePass"; }
+};
+
+struct TestMinPreservingModulePass {
+ PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
+ PreservedAnalyses PA;
+
+ // Force running an analysis.
+ (void)AM->getResult<TestModuleAnalysis>(M);
+
+ PA.preserve<FunctionAnalysisManagerModuleProxy>();
+ return PA;
}
- bool run(Function *F) {
+ static StringRef name() { return "TestMinPreservingModulePass"; }
+};
+
+struct TestFunctionPass {
+ TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
+ int &AnalyzedFunctionCount,
+ bool OnlyUseCachedResults = false)
+ : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
+ AnalyzedFunctionCount(AnalyzedFunctionCount),
+ OnlyUseCachedResults(OnlyUseCachedResults) {}
+
+ PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
++RunCount;
- const TestAnalysisPass::Result &AR = AM.getResult<TestAnalysisPass>(F);
- AnalyzedInstrCount += AR.InstructionCount;
+ const ModuleAnalysisManager &MAM =
+ AM->getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
+ if (TestModuleAnalysis::Result *TMA =
+ MAM.getCachedResult<TestModuleAnalysis>(F->getParent()))
+ AnalyzedFunctionCount += TMA->FunctionCount;
- return true;
+ if (OnlyUseCachedResults) {
+ // Hack to force the use of the cached interface.
+ if (TestFunctionAnalysis::Result *AR =
+ AM->getCachedResult<TestFunctionAnalysis>(F))
+ AnalyzedInstrCount += AR->InstructionCount;
+ } else {
+ // Typical path just runs the analysis as needed.
+ TestFunctionAnalysis::Result &AR = AM->getResult<TestFunctionAnalysis>(F);
+ AnalyzedInstrCount += AR.InstructionCount;
+ }
+
+ return PreservedAnalyses::all();
}
- AnalysisManager &AM;
+ static StringRef name() { return "TestFunctionPass"; }
+
int &RunCount;
int &AnalyzedInstrCount;
+ int &AnalyzedFunctionCount;
+ bool OnlyUseCachedResults;
+};
+
+// A test function pass that invalidates all function analyses for a function
+// with a specific name.
+struct TestInvalidationFunctionPass {
+ TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
+
+ PreservedAnalyses run(Function *F) {
+ return F->getName() == Name ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
+ }
+
+ static StringRef name() { return "TestInvalidationFunctionPass"; }
+
+ StringRef Name;
};
Module *parseIR(const char *IR) {
LLVMContext &C = getGlobalContext();
SMDiagnostic Err;
- return ParseAssemblyString(IR, 0, Err, C);
+ return ParseAssemblyString(IR, nullptr, Err, C);
}
class PassManagerTest : public ::testing::Test {
protected:
- OwningPtr<Module> M;
+ std::unique_ptr<Module> M;
public:
PassManagerTest()
@@ -105,27 +191,154 @@ public:
"}\n")) {}
};
+TEST_F(PassManagerTest, BasicPreservedAnalyses) {
+ PreservedAnalyses PA1 = PreservedAnalyses();
+ EXPECT_FALSE(PA1.preserved<TestFunctionAnalysis>());
+ EXPECT_FALSE(PA1.preserved<TestModuleAnalysis>());
+ PreservedAnalyses PA2 = PreservedAnalyses::none();
+ EXPECT_FALSE(PA2.preserved<TestFunctionAnalysis>());
+ EXPECT_FALSE(PA2.preserved<TestModuleAnalysis>());
+ PreservedAnalyses PA3 = PreservedAnalyses::all();
+ EXPECT_TRUE(PA3.preserved<TestFunctionAnalysis>());
+ EXPECT_TRUE(PA3.preserved<TestModuleAnalysis>());
+ PreservedAnalyses PA4 = PA1;
+ EXPECT_FALSE(PA4.preserved<TestFunctionAnalysis>());
+ EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
+ PA4 = PA3;
+ EXPECT_TRUE(PA4.preserved<TestFunctionAnalysis>());
+ EXPECT_TRUE(PA4.preserved<TestModuleAnalysis>());
+ PA4 = std::move(PA2);
+ EXPECT_FALSE(PA4.preserved<TestFunctionAnalysis>());
+ EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
+ PA4.preserve<TestFunctionAnalysis>();
+ EXPECT_TRUE(PA4.preserved<TestFunctionAnalysis>());
+ EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
+ PA1.preserve<TestModuleAnalysis>();
+ EXPECT_FALSE(PA1.preserved<TestFunctionAnalysis>());
+ EXPECT_TRUE(PA1.preserved<TestModuleAnalysis>());
+ PA1.preserve<TestFunctionAnalysis>();
+ EXPECT_TRUE(PA1.preserved<TestFunctionAnalysis>());
+ EXPECT_TRUE(PA1.preserved<TestModuleAnalysis>());
+ PA1.intersect(PA4);
+ EXPECT_TRUE(PA1.preserved<TestFunctionAnalysis>());
+ EXPECT_FALSE(PA1.preserved<TestModuleAnalysis>());
+}
+
TEST_F(PassManagerTest, Basic) {
- AnalysisManager AM(M.get());
- AM.registerAnalysisPass(TestAnalysisPass());
+ FunctionAnalysisManager FAM;
+ int FunctionAnalysisRuns = 0;
+ FAM.registerPass(TestFunctionAnalysis(FunctionAnalysisRuns));
- ModulePassManager MPM(M.get(), &AM);
- FunctionPassManager FPM(&AM);
+ ModuleAnalysisManager MAM;
+ int ModuleAnalysisRuns = 0;
+ MAM.registerPass(TestModuleAnalysis(ModuleAnalysisRuns));
+ MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
+ FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM));
+
+ ModulePassManager MPM;
+
+ // Count the runs over a Function.
+ int FunctionPassRunCount1 = 0;
+ int AnalyzedInstrCount1 = 0;
+ int AnalyzedFunctionCount1 = 0;
+ {
+ // Pointless scoped copy to test move assignment.
+ ModulePassManager NestedMPM;
+ FunctionPassManager FPM;
+ {
+ // Pointless scope to test move assignment.
+ FunctionPassManager NestedFPM;
+ NestedFPM.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1,
+ AnalyzedFunctionCount1));
+ FPM = std::move(NestedFPM);
+ }
+ NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ MPM = std::move(NestedMPM);
+ }
// Count the runs over a module.
int ModulePassRunCount = 0;
MPM.addPass(TestModulePass(ModulePassRunCount));
- // Count the runs over a Function.
- int FunctionPassRunCount = 0;
- int AnalyzedInstrCount = 0;
- FPM.addPass(TestFunctionPass(AM, FunctionPassRunCount, AnalyzedInstrCount));
- MPM.addPass(FPM);
+ // Count the runs over a Function in a separate manager.
+ int FunctionPassRunCount2 = 0;
+ int AnalyzedInstrCount2 = 0;
+ int AnalyzedFunctionCount2 = 0;
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
+ AnalyzedFunctionCount2));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
+
+ // A third function pass manager but with only preserving intervening passes
+ // and with a function pass that invalidates exactly one analysis.
+ MPM.addPass(TestPreservingModulePass());
+ int FunctionPassRunCount3 = 0;
+ int AnalyzedInstrCount3 = 0;
+ int AnalyzedFunctionCount3 = 0;
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
+ AnalyzedFunctionCount3));
+ FPM.addPass(TestInvalidationFunctionPass("f"));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
+
+ // A fourth function pass manager but with a minimal intervening passes.
+ MPM.addPass(TestMinPreservingModulePass());
+ int FunctionPassRunCount4 = 0;
+ int AnalyzedInstrCount4 = 0;
+ int AnalyzedFunctionCount4 = 0;
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
+ AnalyzedFunctionCount4));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
- MPM.run();
+ // A fifth function pass manager but which uses only cached results.
+ int FunctionPassRunCount5 = 0;
+ int AnalyzedInstrCount5 = 0;
+ int AnalyzedFunctionCount5 = 0;
+ {
+ FunctionPassManager FPM;
+ FPM.addPass(TestInvalidationFunctionPass("f"));
+ FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
+ AnalyzedFunctionCount5,
+ /*OnlyUseCachedResults=*/true));
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+ }
+
+ MPM.run(M.get(), &MAM);
+
+ // Validate module pass counters.
EXPECT_EQ(1, ModulePassRunCount);
- EXPECT_EQ(3, FunctionPassRunCount);
- EXPECT_EQ(5, AnalyzedInstrCount);
-}
+ // Validate all function pass counter sets are the same.
+ EXPECT_EQ(3, FunctionPassRunCount1);
+ EXPECT_EQ(5, AnalyzedInstrCount1);
+ EXPECT_EQ(0, AnalyzedFunctionCount1);
+ EXPECT_EQ(3, FunctionPassRunCount2);
+ EXPECT_EQ(5, AnalyzedInstrCount2);
+ EXPECT_EQ(0, AnalyzedFunctionCount2);
+ EXPECT_EQ(3, FunctionPassRunCount3);
+ EXPECT_EQ(5, AnalyzedInstrCount3);
+ EXPECT_EQ(0, AnalyzedFunctionCount3);
+ EXPECT_EQ(3, FunctionPassRunCount4);
+ EXPECT_EQ(5, AnalyzedInstrCount4);
+ EXPECT_EQ(0, AnalyzedFunctionCount4);
+ EXPECT_EQ(3, FunctionPassRunCount5);
+ EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
+ EXPECT_EQ(0, AnalyzedFunctionCount5);
+
+ // Validate the analysis counters:
+ // first run over 3 functions, then module pass invalidates
+ // second run over 3 functions, nothing invalidates
+ // third run over 0 functions, but 1 function invalidated
+ // fourth run over 1 function
+ EXPECT_EQ(7, FunctionAnalysisRuns);
+
+ EXPECT_EQ(1, ModuleAnalysisRuns);
+}
}
diff --git a/unittests/IR/PatternMatch.cpp b/unittests/IR/PatternMatch.cpp
index 7c6d8ce61586..f3a27b8d2509 100644
--- a/unittests/IR/PatternMatch.cpp
+++ b/unittests/IR/PatternMatch.cpp
@@ -13,253 +13,286 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
#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 "llvm/Support/NoFolder.h"
-#include "llvm/Support/PatternMatch.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Type.h"
#include "gtest/gtest.h"
+using namespace llvm;
using namespace llvm::PatternMatch;
-namespace llvm {
namespace {
-/// Ordered floating point minimum/maximum tests.
-
-static void m_OrdFMin_expect_match_and_delete(Value *Cmp, Value *Select,
- Value *L, Value *R) {
- Value *MatchL, *MatchR;
- EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
- EXPECT_EQ(L, MatchL);
- EXPECT_EQ(R, MatchR);
- delete Select;
- delete Cmp;
-}
-
-static void m_OrdFMin_expect_nomatch_and_delete(Value *Cmp, Value *Select,
- Value *L, Value *R) {
- Value *MatchL, *MatchR;
- EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
- delete Select;
- delete Cmp;
+struct PatternMatchTest : ::testing::Test {
+ LLVMContext Ctx;
+ std::unique_ptr<Module> M;
+ Function *F;
+ BasicBlock *BB;
+ IRBuilder<true, NoFolder> IRB;
+
+ PatternMatchTest()
+ : M(new Module("PatternMatchTestModule", Ctx)),
+ F(Function::Create(
+ FunctionType::get(Type::getVoidTy(Ctx), /* IsVarArg */ false),
+ Function::ExternalLinkage, "f", M.get())),
+ BB(BasicBlock::Create(Ctx, "entry", F)), IRB(BB) {}
+};
+
+TEST_F(PatternMatchTest, OneUse) {
+ // Build up a little tree of values:
+ //
+ // One = (1 + 2) + 42
+ // Two = One + 42
+ // Leaf = (Two + 8) + (Two + 13)
+ Value *One = IRB.CreateAdd(IRB.CreateAdd(IRB.getInt32(1), IRB.getInt32(2)),
+ IRB.getInt32(42));
+ Value *Two = IRB.CreateAdd(One, IRB.getInt32(42));
+ Value *Leaf = IRB.CreateAdd(IRB.CreateAdd(Two, IRB.getInt32(8)),
+ IRB.CreateAdd(Two, IRB.getInt32(13)));
+ Value *V;
+
+ EXPECT_TRUE(m_OneUse(m_Value(V)).match(One));
+ EXPECT_EQ(One, V);
+
+ EXPECT_FALSE(m_OneUse(m_Value()).match(Two));
+ EXPECT_FALSE(m_OneUse(m_Value()).match(Leaf));
}
-static void m_OrdFMax_expect_match_and_delete(Value *Cmp, Value *Select,
- Value *L, Value *R) {
- Value *MatchL, *MatchR;
- EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
- EXPECT_EQ(L, MatchL);
- EXPECT_EQ(R, MatchR);
- delete Select;
- delete Cmp;
-}
-
-static void m_OrdFMax_expect_nomatch_and_delete(Value *Cmp, Value *Select,
- Value *L, Value *R) {
- Value *MatchL, *MatchR;
- EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
- delete Select;
- delete Cmp;
-}
-
-
-
-TEST(PatternMatchTest, FloatingPointOrderedMin) {
- LLVMContext &C(getGlobalContext());
- IRBuilder<true, NoFolder> Builder(C);
-
- Type *FltTy = Builder.getFloatTy();
+TEST_F(PatternMatchTest, FloatingPointOrderedMin) {
+ Type *FltTy = IRB.getFloatTy();
Value *L = ConstantFP::get(FltTy, 1.0);
Value *R = ConstantFP::get(FltTy, 2.0);
+ Value *MatchL, *MatchR;
// Test OLT.
- Value *Cmp = Builder.CreateFCmpOLT(L, R);
- Value *Select = Builder.CreateSelect(Cmp, L, R);
- m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test OLE.
- Cmp = Builder.CreateFCmpOLE(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test no match on OGE.
- Cmp = Builder.CreateFCmpOGE(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_OrdFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
+ EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));
// Test no match on OGT.
- Cmp = Builder.CreateFCmpOGT(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_OrdFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
+ EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
// Test match on OGE with inverted select.
- Cmp = Builder.CreateFCmpOGE(L, R);
- Select = Builder.CreateSelect(Cmp, R, L);
- m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test match on OGT with inverted select.
- Cmp = Builder.CreateFCmpOGT(L, R);
- Select = Builder.CreateSelect(Cmp, R, L);
- m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
}
-TEST(PatternMatchTest, FloatingPointOrderedMax) {
- LLVMContext &C(getGlobalContext());
- IRBuilder<true, NoFolder> Builder(C);
-
- Type *FltTy = Builder.getFloatTy();
+TEST_F(PatternMatchTest, FloatingPointOrderedMax) {
+ Type *FltTy = IRB.getFloatTy();
Value *L = ConstantFP::get(FltTy, 1.0);
Value *R = ConstantFP::get(FltTy, 2.0);
+ Value *MatchL, *MatchR;
// Test OGT.
- Value *Cmp = Builder.CreateFCmpOGT(L, R);
- Value *Select = Builder.CreateSelect(Cmp, L, R);
- m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test OGE.
- Cmp = Builder.CreateFCmpOGE(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test no match on OLE.
- Cmp = Builder.CreateFCmpOLE(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_OrdFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
+ EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));
// Test no match on OLT.
- Cmp = Builder.CreateFCmpOLT(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_OrdFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
+ EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
// Test match on OLE with inverted select.
- Cmp = Builder.CreateFCmpOLE(L, R);
- Select = Builder.CreateSelect(Cmp, R, L);
- m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
-
- // Test match on OLT with inverted select.
- Cmp = Builder.CreateFCmpOLT(L, R);
- Select = Builder.CreateSelect(Cmp, R, L);
- m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
-}
-
-/// Unordered floating point minimum/maximum tests.
-
-static void m_UnordFMin_expect_match_and_delete(Value *Cmp, Value *Select,
- Value *L, Value *R) {
- Value *MatchL, *MatchR;
- EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));
EXPECT_EQ(L, MatchL);
EXPECT_EQ(R, MatchR);
- delete Select;
- delete Cmp;
-}
-static void m_UnordFMin_expect_nomatch_and_delete(Value *Cmp, Value *Select,
- Value *L, Value *R) {
- Value *MatchL, *MatchR;
- EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
- delete Select;
- delete Cmp;
-}
-
-static void m_UnordFMax_expect_match_and_delete(Value *Cmp, Value *Select,
- Value *L, Value *R) {
- Value *MatchL, *MatchR;
- EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ // Test match on OLT with inverted select.
+ EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));
EXPECT_EQ(L, MatchL);
EXPECT_EQ(R, MatchR);
- delete Select;
- delete Cmp;
-}
-
-static void m_UnordFMax_expect_nomatch_and_delete(Value *Cmp, Value *Select,
- Value *L, Value *R) {
- Value *MatchL, *MatchR;
- EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
- delete Select;
- delete Cmp;
}
-TEST(PatternMatchTest, FloatingPointUnorderedMin) {
- LLVMContext &C(getGlobalContext());
- IRBuilder<true, NoFolder> Builder(C);
-
- Type *FltTy = Builder.getFloatTy();
+TEST_F(PatternMatchTest, FloatingPointUnorderedMin) {
+ Type *FltTy = IRB.getFloatTy();
Value *L = ConstantFP::get(FltTy, 1.0);
Value *R = ConstantFP::get(FltTy, 2.0);
+ Value *MatchL, *MatchR;
// Test ULT.
- Value *Cmp = Builder.CreateFCmpULT(L, R);
- Value *Select = Builder.CreateSelect(Cmp, L, R);
- m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test ULE.
- Cmp = Builder.CreateFCmpULE(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test no match on UGE.
- Cmp = Builder.CreateFCmpUGE(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_UnordFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
+ EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));
// Test no match on UGT.
- Cmp = Builder.CreateFCmpUGT(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_UnordFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
+ EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
// Test match on UGE with inverted select.
- Cmp = Builder.CreateFCmpUGE(L, R);
- Select = Builder.CreateSelect(Cmp, R, L);
- m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test match on UGT with inverted select.
- Cmp = Builder.CreateFCmpUGT(L, R);
- Select = Builder.CreateSelect(Cmp, R, L);
- m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
}
-TEST(PatternMatchTest, FloatingPointUnorderedMax) {
- LLVMContext &C(getGlobalContext());
- IRBuilder<true, NoFolder> Builder(C);
-
- Type *FltTy = Builder.getFloatTy();
+TEST_F(PatternMatchTest, FloatingPointUnorderedMax) {
+ Type *FltTy = IRB.getFloatTy();
Value *L = ConstantFP::get(FltTy, 1.0);
Value *R = ConstantFP::get(FltTy, 2.0);
+ Value *MatchL, *MatchR;
// Test UGT.
- Value *Cmp = Builder.CreateFCmpUGT(L, R);
- Value *Select = Builder.CreateSelect(Cmp, L, R);
- m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test UGE.
- Cmp = Builder.CreateFCmpUGE(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test no match on ULE.
- Cmp = Builder.CreateFCmpULE(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_UnordFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
+ EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));
// Test no match on ULT.
- Cmp = Builder.CreateFCmpULT(L, R);
- Select = Builder.CreateSelect(Cmp, L, R);
- m_UnordFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
+ EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
// Test match on ULE with inverted select.
- Cmp = Builder.CreateFCmpULE(L, R);
- Select = Builder.CreateSelect(Cmp, R, L);
- m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
// Test match on ULT with inverted select.
- Cmp = Builder.CreateFCmpULT(L, R);
- Select = Builder.CreateSelect(Cmp, R, L);
- m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
+ EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+ .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+}
+
+TEST_F(PatternMatchTest, OverflowingBinOps) {
+ Value *L = IRB.getInt32(1);
+ Value *R = IRB.getInt32(2);
+ Value *MatchL, *MatchR;
+
+ EXPECT_TRUE(
+ m_NSWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWAdd(L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ MatchL = MatchR = nullptr;
+ EXPECT_TRUE(
+ m_NSWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWSub(L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ MatchL = MatchR = nullptr;
+ EXPECT_TRUE(
+ m_NSWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWMul(L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ MatchL = MatchR = nullptr;
+ EXPECT_TRUE(m_NSWShl(m_Value(MatchL), m_Value(MatchR)).match(
+ IRB.CreateShl(L, R, "", /* NUW */ false, /* NSW */ true)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+
+ EXPECT_TRUE(
+ m_NUWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWAdd(L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ MatchL = MatchR = nullptr;
+ EXPECT_TRUE(
+ m_NUWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWSub(L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ MatchL = MatchR = nullptr;
+ EXPECT_TRUE(
+ m_NUWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWMul(L, R)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ MatchL = MatchR = nullptr;
+ EXPECT_TRUE(m_NUWShl(m_Value(MatchL), m_Value(MatchR)).match(
+ IRB.CreateShl(L, R, "", /* NUW */ true, /* NSW */ false)));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+
+ EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R)));
+ EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
+ EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R)));
+ EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R)));
+ EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R)));
+ EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
+ EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R)));
+ EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNUWMul(L, R)));
+ EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
+ EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R)));
+ EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(
+ IRB.CreateShl(L, R, "", /* NUW */ true, /* NSW */ false)));
+ EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
+
+ EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R)));
+ EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
+ EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R)));
+ EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R)));
+ EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R)));
+ EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
+ EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R)));
+ EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNSWMul(L, R)));
+ EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
+ EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R)));
+ EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(
+ IRB.CreateShl(L, R, "", /* NUW */ false, /* NSW */ true)));
+ EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
}
} // anonymous namespace.
-} // llvm namespace.
diff --git a/unittests/IR/TypeBuilderTest.cpp b/unittests/IR/TypeBuilderTest.cpp
index be493cdc6396..b7b3e45e35ed 100644
--- a/unittests/IR/TypeBuilderTest.cpp
+++ b/unittests/IR/TypeBuilderTest.cpp
@@ -234,19 +234,19 @@ TEST(TypeBuilderTest, Extensions) {
TypeBuilder<int, false>::get(getGlobalContext()),
TypeBuilder<int*, false>::get(getGlobalContext()),
TypeBuilder<void*[], false>::get(getGlobalContext()),
- (void*)0)),
+ (void*)nullptr)),
(TypeBuilder<MyType*, false>::get(getGlobalContext())));
EXPECT_EQ(PointerType::getUnqual(StructType::get(
TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
- (void*)0)),
+ (void*)nullptr)),
(TypeBuilder<MyPortableType*, false>::get(getGlobalContext())));
EXPECT_EQ(PointerType::getUnqual(StructType::get(
TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
- (void*)0)),
+ (void*)nullptr)),
(TypeBuilder<MyPortableType*, true>::get(getGlobalContext())));
}
diff --git a/unittests/IR/UserTest.cpp b/unittests/IR/UserTest.cpp
new file mode 100644
index 000000000000..eb07e824d8b8
--- /dev/null
+++ b/unittests/IR/UserTest.cpp
@@ -0,0 +1,96 @@
+//===- llvm/unittest/IR/UserTest.cpp - User unit tests --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+
+TEST(UserTest, ValueOpIteration) {
+ LLVMContext C;
+
+ const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n"
+ "entry:\n"
+ " switch i32 undef, label %s0\n"
+ " [ i32 1, label %s1\n"
+ " i32 2, label %s2\n"
+ " i32 3, label %s3\n"
+ " i32 4, label %s4\n"
+ " i32 5, label %s5\n"
+ " i32 6, label %s6\n"
+ " i32 7, label %s7\n"
+ " i32 8, label %s8\n"
+ " i32 9, label %s9 ]\n"
+ "\n"
+ "s0:\n"
+ " br label %exit\n"
+ "s1:\n"
+ " br label %exit\n"
+ "s2:\n"
+ " br label %exit\n"
+ "s3:\n"
+ " br label %exit\n"
+ "s4:\n"
+ " br label %exit\n"
+ "s5:\n"
+ " br label %exit\n"
+ "s6:\n"
+ " br label %exit\n"
+ "s7:\n"
+ " br label %exit\n"
+ "s8:\n"
+ " br label %exit\n"
+ "s9:\n"
+ " br label %exit\n"
+ "\n"
+ "exit:\n"
+ " %phi = phi i32 [ 0, %s0 ], [ 1, %s1 ],\n"
+ " [ 2, %s2 ], [ 3, %s3 ],\n"
+ " [ 4, %s4 ], [ 5, %s5 ],\n"
+ " [ 6, %s6 ], [ 7, %s7 ],\n"
+ " [ 8, %s8 ], [ 9, %s9 ]\n"
+ " ret void\n"
+ "}\n";
+ SMDiagnostic Err;
+ Module *M = ParseAssemblyString(ModuleString, nullptr, Err, C);
+
+ Function *F = M->getFunction("f");
+ BasicBlock &ExitBB = F->back();
+ PHINode &P = cast<PHINode>(ExitBB.front());
+ EXPECT_TRUE(P.value_op_begin() == P.value_op_begin());
+ EXPECT_FALSE(P.value_op_begin() == P.value_op_end());
+ EXPECT_TRUE(P.value_op_begin() != P.value_op_end());
+ EXPECT_FALSE(P.value_op_end() != P.value_op_end());
+ EXPECT_TRUE(P.value_op_begin() < P.value_op_end());
+ EXPECT_FALSE(P.value_op_begin() < P.value_op_begin());
+ EXPECT_TRUE(P.value_op_end() > P.value_op_begin());
+ EXPECT_FALSE(P.value_op_begin() > P.value_op_begin());
+ EXPECT_TRUE(P.value_op_begin() <= P.value_op_begin());
+ EXPECT_FALSE(P.value_op_end() <= P.value_op_begin());
+ EXPECT_TRUE(P.value_op_begin() >= P.value_op_begin());
+ EXPECT_FALSE(P.value_op_begin() >= P.value_op_end());
+ EXPECT_EQ(10, std::distance(P.value_op_begin(), P.value_op_end()));
+
+ User::value_op_iterator I = P.value_op_begin();
+ I += 3;
+ EXPECT_EQ(std::next(P.value_op_begin(), 3), I);
+ EXPECT_EQ(P.getOperand(3), *I);
+ I++;
+ EXPECT_EQ(P.getOperand(6), I[2]);
+ EXPECT_EQ(P.value_op_end(), (I - 2) + 8);
+}
+
+} // end anonymous namespace
diff --git a/unittests/Support/ValueHandleTest.cpp b/unittests/IR/ValueHandleTest.cpp
index 05aafa2d05d8..403d2bcbda16 100644
--- a/unittests/Support/ValueHandleTest.cpp
+++ b/unittests/IR/ValueHandleTest.cpp
@@ -1,4 +1,4 @@
-//===- llvm/unittest/Support/ValueHandleTest.cpp - ValueHandle tests --------===//
+//===- ValueHandleTest.cpp - ValueHandle tests ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
@@ -95,7 +94,7 @@ TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
WeakVH WVH_Copy(WVH);
WeakVH WVH_Recreated(BitcastV.get());
BitcastV.reset();
- Value *null_value = NULL;
+ Value *null_value = nullptr;
EXPECT_EQ(null_value, WVH);
EXPECT_EQ(null_value, WVH_Copy);
EXPECT_EQ(null_value, WVH_Recreated);
@@ -179,10 +178,10 @@ TEST_F(ValueHandle, AssertingVH_Asserts) {
EXPECT_DEATH({BitcastV.reset();},
"An asserting value handle still pointed to this value!");
AssertingVH<Value> Copy(AVH);
- AVH = NULL;
+ AVH = nullptr;
EXPECT_DEATH({BitcastV.reset();},
"An asserting value handle still pointed to this value!");
- Copy = NULL;
+ Copy = nullptr;
BitcastV.reset();
}
@@ -264,14 +263,14 @@ TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
int DeletedCalls;
Value *AURWArgument;
- RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {}
+ RecordingVH() : DeletedCalls(0), AURWArgument(nullptr) {}
RecordingVH(Value *V)
- : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
+ : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr) {}
private:
virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
virtual void allUsesReplacedWith(Value *new_value) {
- EXPECT_EQ(NULL, AURWArgument);
+ EXPECT_EQ(nullptr, AURWArgument);
AURWArgument = new_value;
}
};
@@ -279,7 +278,7 @@ TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
RecordingVH RVH;
RVH = BitcastV.get();
EXPECT_EQ(0, RVH.DeletedCalls);
- EXPECT_EQ(NULL, RVH.AURWArgument);
+ EXPECT_EQ(nullptr, RVH.AURWArgument);
BitcastV->replaceAllUsesWith(ConstantV);
EXPECT_EQ(0, RVH.DeletedCalls);
EXPECT_EQ(ConstantV, RVH.AURWArgument);
@@ -292,21 +291,21 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
Value *AURWArgument;
LLVMContext *Context;
- RecoveringVH() : DeletedCalls(0), AURWArgument(NULL),
+ RecoveringVH() : DeletedCalls(0), AURWArgument(nullptr),
Context(&getGlobalContext()) {}
RecoveringVH(Value *V)
- : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL),
+ : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr),
Context(&getGlobalContext()) {}
private:
virtual void deleted() {
getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
- setValPtr(NULL);
+ setValPtr(nullptr);
}
virtual void allUsesReplacedWith(Value *new_value) {
- ASSERT_TRUE(NULL != getValPtr());
+ ASSERT_TRUE(nullptr != getValPtr());
EXPECT_EQ(1U, getValPtr()->getNumUses());
- EXPECT_EQ(NULL, AURWArgument);
+ EXPECT_EQ(nullptr, AURWArgument);
AURWArgument = new_value;
}
};
@@ -336,7 +335,7 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
class DestroyingVH : public CallbackVH {
public:
- OwningPtr<WeakVH> ToClear[2];
+ std::unique_ptr<WeakVH> ToClear[2];
DestroyingVH(Value *V) {
ToClear[0].reset(new WeakVH(V));
setValPtr(V);
@@ -369,8 +368,8 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
WeakVH ShouldBeVisited2(BitcastV.get());
BitcastV.reset();
- EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited1));
- EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited2));
+ EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1));
+ EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited2));
}
}
@@ -390,8 +389,8 @@ TEST_F(ValueHandle, AssertingVHCheckedLast) {
}
virtual void deleted() {
- *ToClear[0] = 0;
- *ToClear[1] = 0;
+ *ToClear[0] = nullptr;
+ *ToClear[1] = nullptr;
CallbackVH::deleted();
}
};
diff --git a/unittests/IR/ValueMapTest.cpp b/unittests/IR/ValueMapTest.cpp
index 5aaf90583628..0b7198fc6ecb 100644
--- a/unittests/IR/ValueMapTest.cpp
+++ b/unittests/IR/ValueMapTest.cpp
@@ -7,8 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/ValueMap.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/IR/ValueMap.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
@@ -24,8 +23,8 @@ template<typename T>
class ValueMapTest : public testing::Test {
protected:
Constant *ConstantV;
- OwningPtr<BitCastInst> BitcastV;
- OwningPtr<BinaryOperator> AddV;
+ std::unique_ptr<BitCastInst> BitcastV;
+ std::unique_ptr<BinaryOperator> AddV;
ValueMapTest() :
ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
@@ -41,21 +40,21 @@ TYPED_TEST_CASE(ValueMapTest, KeyTypes);
TYPED_TEST(ValueMapTest, Null) {
ValueMap<TypeParam*, int> VM1;
- VM1[NULL] = 7;
- EXPECT_EQ(7, VM1.lookup(NULL));
+ VM1[nullptr] = 7;
+ EXPECT_EQ(7, VM1.lookup(nullptr));
}
TYPED_TEST(ValueMapTest, FollowsValue) {
ValueMap<TypeParam*, int> VM;
VM[this->BitcastV.get()] = 7;
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
- EXPECT_EQ(0, VM.count(this->AddV.get()));
+ EXPECT_EQ(0u, VM.count(this->AddV.get()));
this->BitcastV->replaceAllUsesWith(this->AddV.get());
EXPECT_EQ(7, VM.lookup(this->AddV.get()));
- EXPECT_EQ(0, VM.count(this->BitcastV.get()));
+ EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
this->AddV.reset();
- EXPECT_EQ(0, VM.count(this->AddV.get()));
- EXPECT_EQ(0, VM.count(this->BitcastV.get()));
+ EXPECT_EQ(0u, VM.count(this->AddV.get()));
+ EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
EXPECT_EQ(0U, VM.size());
}
@@ -91,7 +90,7 @@ TYPED_TEST(ValueMapTest, OperationsWork) {
EXPECT_EQ(this->AddV.get(), InsertResult1.first->first);
EXPECT_EQ(3, InsertResult1.first->second);
EXPECT_TRUE(InsertResult1.second);
- EXPECT_EQ(true, VM.count(this->AddV.get()));
+ EXPECT_EQ(1u, VM.count(this->AddV.get()));
std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult2 =
VM.insert(std::make_pair(this->AddV.get(), 5));
EXPECT_EQ(this->AddV.get(), InsertResult2.first->first);
@@ -117,7 +116,8 @@ TYPED_TEST(ValueMapTest, OperationsWork) {
template<typename ExpectedType, typename VarType>
void CompileAssertHasType(VarType) {
- typedef char assert[is_same<ExpectedType, VarType>::value ? 1 : -1];
+ static_assert(std::is_same<ExpectedType, VarType>::value,
+ "Not the same type");
}
TYPED_TEST(ValueMapTest, Iteration) {
@@ -169,7 +169,7 @@ TYPED_TEST(ValueMapTest, DefaultCollisionBehavior) {
VM[this->BitcastV.get()] = 7;
VM[this->AddV.get()] = 9;
this->BitcastV->replaceAllUsesWith(this->AddV.get());
- EXPECT_EQ(0, VM.count(this->BitcastV.get()));
+ EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
EXPECT_EQ(9, VM.lookup(this->AddV.get()));
}
@@ -177,10 +177,10 @@ TYPED_TEST(ValueMapTest, ConfiguredCollisionBehavior) {
// TODO: Implement this when someone needs it.
}
-template<typename KeyT>
-struct LockMutex : ValueMapConfig<KeyT> {
+template<typename KeyT, typename MutexT>
+struct LockMutex : ValueMapConfig<KeyT, MutexT> {
struct ExtraData {
- sys::Mutex *M;
+ MutexT *M;
bool *CalledRAUW;
bool *CalledDeleted;
};
@@ -192,15 +192,15 @@ struct LockMutex : ValueMapConfig<KeyT> {
*Data.CalledDeleted = true;
EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked.";
}
- static sys::Mutex *getMutex(const ExtraData &Data) { return Data.M; }
+ static MutexT *getMutex(const ExtraData &Data) { return Data.M; }
};
#if LLVM_ENABLE_THREADS
TYPED_TEST(ValueMapTest, LocksMutex) {
sys::Mutex M(false); // Not recursive.
bool CalledRAUW = false, CalledDeleted = false;
- typename LockMutex<TypeParam*>::ExtraData Data =
- {&M, &CalledRAUW, &CalledDeleted};
- ValueMap<TypeParam*, int, LockMutex<TypeParam*> > VM(Data);
+ typedef LockMutex<TypeParam*, sys::Mutex> ConfigType;
+ typename ConfigType::ExtraData Data = {&M, &CalledRAUW, &CalledDeleted};
+ ValueMap<TypeParam*, int, ConfigType> VM(Data);
VM[this->BitcastV.get()] = 7;
this->BitcastV->replaceAllUsesWith(this->AddV.get());
this->AddV.reset();
@@ -218,7 +218,7 @@ TYPED_TEST(ValueMapTest, NoFollowRAUW) {
ValueMap<TypeParam*, int, NoFollow<TypeParam*> > VM;
VM[this->BitcastV.get()] = 7;
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
- EXPECT_EQ(0, VM.count(this->AddV.get()));
+ EXPECT_EQ(0u, VM.count(this->AddV.get()));
this->BitcastV->replaceAllUsesWith(this->AddV.get());
EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
EXPECT_EQ(0, VM.lookup(this->AddV.get()));
@@ -284,11 +284,11 @@ TYPED_TEST(ValueMapTest, SurvivesModificationByConfig) {
// Now the ModifyingConfig can modify the Map inside a callback.
VM[this->BitcastV.get()] = 7;
this->BitcastV->replaceAllUsesWith(this->AddV.get());
- EXPECT_FALSE(VM.count(this->BitcastV.get()));
- EXPECT_FALSE(VM.count(this->AddV.get()));
+ EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
+ EXPECT_EQ(0u, VM.count(this->AddV.get()));
VM[this->AddV.get()] = 7;
this->AddV.reset();
- EXPECT_FALSE(VM.count(this->AddV.get()));
+ EXPECT_EQ(0u, VM.count(this->AddV.get()));
}
}
diff --git a/unittests/IR/ValueTest.cpp b/unittests/IR/ValueTest.cpp
index ebe23e869401..61e44a908d4e 100644
--- a/unittests/IR/ValueTest.cpp
+++ b/unittests/IR/ValueTest.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Assembly/Parser.h"
+#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
@@ -34,7 +34,7 @@ TEST(ValueTest, UsedInBasicBlock) {
" ret void\n"
"}\n";
SMDiagnostic Err;
- Module *M = ParseAssemblyString(ModuleString, NULL, Err, C);
+ Module *M = ParseAssemblyString(ModuleString, nullptr, Err, C);
Function *F = M->getFunction("f");
@@ -45,7 +45,7 @@ TEST(ValueTest, UsedInBasicBlock) {
TEST(GlobalTest, CreateAddressSpace) {
LLVMContext &Ctx = getGlobalContext();
- OwningPtr<Module> M(new Module("TestModule", Ctx));
+ std::unique_ptr<Module> M(new Module("TestModule", Ctx));
Type *Int8Ty = Type::getInt8Ty(Ctx);
Type *Int32Ty = Type::getInt32Ty(Ctx);
@@ -56,7 +56,7 @@ TEST(GlobalTest, CreateAddressSpace) {
GlobalValue::ExternalLinkage,
Constant::getAllOnesValue(Int32Ty),
"dummy",
- 0,
+ nullptr,
GlobalVariable::NotThreadLocal,
1);
@@ -74,7 +74,7 @@ TEST(GlobalTest, CreateAddressSpace) {
GlobalValue::ExternalLinkage,
Constant::getAllOnesValue(Int32Ty),
"dummy_cast",
- 0,
+ nullptr,
GlobalVariable::NotThreadLocal,
1);
diff --git a/unittests/IR/VerifierTest.cpp b/unittests/IR/VerifierTest.cpp
index 31936c392d84..71e3168b686b 100644
--- a/unittests/IR/VerifierTest.cpp
+++ b/unittests/IR/VerifierTest.cpp
@@ -7,8 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/IR/Verifier.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
@@ -42,24 +41,7 @@ TEST(VerifierTest, Branch_i1) {
Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0);
BI->setOperand(0, Zero32);
- EXPECT_TRUE(verifyFunction(*F, ReturnStatusAction));
-}
-
-TEST(VerifierTest, AliasUnnamedAddr) {
- LLVMContext &C = getGlobalContext();
- Module M("M", C);
- Type *Ty = Type::getInt8Ty(C);
- Constant *Init = Constant::getNullValue(Ty);
- GlobalVariable *Aliasee = new GlobalVariable(M, Ty, true,
- GlobalValue::ExternalLinkage,
- Init, "foo");
- GlobalAlias *GA = new GlobalAlias(Type::getInt8PtrTy(C),
- GlobalValue::ExternalLinkage,
- "bar", Aliasee, &M);
- GA->setUnnamedAddr(true);
- std::string Error;
- EXPECT_TRUE(verifyModule(M, ReturnStatusAction, &Error));
- EXPECT_TRUE(StringRef(Error).startswith("Alias cannot have unnamed_addr"));
+ EXPECT_TRUE(verifyFunction(*F));
}
TEST(VerifierTest, InvalidRetAttribute) {
@@ -72,9 +54,10 @@ TEST(VerifierTest, InvalidRetAttribute) {
Attribute::UWTable));
std::string Error;
- EXPECT_TRUE(verifyModule(M, ReturnStatusAction, &Error));
- EXPECT_TRUE(StringRef(Error).
- startswith("Attribute 'uwtable' only applies to functions!"));
+ raw_string_ostream ErrorOS(Error);
+ EXPECT_TRUE(verifyModule(M, &ErrorOS));
+ EXPECT_TRUE(StringRef(ErrorOS.str()).startswith(
+ "Attribute 'uwtable' only applies to functions!"));
}
}
diff --git a/unittests/IR/WaymarkTest.cpp b/unittests/IR/WaymarkTest.cpp
index 9a9b4a2ad4e7..8e3cd45808f8 100644
--- a/unittests/IR/WaymarkTest.cpp
+++ b/unittests/IR/WaymarkTest.cpp
@@ -31,7 +31,7 @@ TEST(WaymarkTest, NativeArray) {
FunctionType *FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), true);
Function *F = Function::Create(FT, GlobalValue::ExternalLinkage);
const CallInst *A = CallInst::Create(F, makeArrayRef(values));
- ASSERT_NE(A, (const CallInst*)NULL);
+ ASSERT_NE(A, (const CallInst*)nullptr);
ASSERT_EQ(1U + 22, A->getNumOperands());
const Use *U = &A->getOperandUse(0);
const Use *Ue = &A->getOperandUse(22);
diff --git a/unittests/LineEditor/CMakeLists.txt b/unittests/LineEditor/CMakeLists.txt
new file mode 100644
index 000000000000..c6823d8f9098
--- /dev/null
+++ b/unittests/LineEditor/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+ LineEditor
+ )
+
+add_llvm_unittest(LineEditorTests
+ LineEditor.cpp
+ )
diff --git a/unittests/LineEditor/LineEditor.cpp b/unittests/LineEditor/LineEditor.cpp
new file mode 100644
index 000000000000..26053c0ede24
--- /dev/null
+++ b/unittests/LineEditor/LineEditor.cpp
@@ -0,0 +1,83 @@
+//===-- LineEditor.cpp ----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/LineEditor/LineEditor.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+class LineEditorTest : public testing::Test {
+public:
+ SmallString<64> HistPath;
+ LineEditor *LE;
+
+ LineEditorTest() {
+ init();
+ }
+
+ void init() {
+ sys::fs::createTemporaryFile("temp", "history", HistPath);
+ ASSERT_FALSE(HistPath.empty());
+ LE = new LineEditor("test", HistPath);
+ }
+
+ ~LineEditorTest() {
+ delete LE;
+ sys::fs::remove(HistPath.str());
+ }
+};
+
+TEST_F(LineEditorTest, HistorySaveLoad) {
+ LE->saveHistory();
+ LE->loadHistory();
+}
+
+struct TestListCompleter {
+ std::vector<LineEditor::Completion> Completions;
+
+ TestListCompleter(const std::vector<LineEditor::Completion> &Completions)
+ : Completions(Completions) {}
+
+ std::vector<LineEditor::Completion> operator()(StringRef Buffer,
+ size_t Pos) const {
+ EXPECT_TRUE(Buffer.empty());
+ EXPECT_EQ(0u, Pos);
+ return Completions;
+ }
+};
+
+TEST_F(LineEditorTest, ListCompleters) {
+ std::vector<LineEditor::Completion> Comps;
+
+ Comps.push_back(LineEditor::Completion("foo", "int foo()"));
+ LE->setListCompleter(TestListCompleter(Comps));
+ LineEditor::CompletionAction CA = LE->getCompletionAction("", 0);
+ EXPECT_EQ(LineEditor::CompletionAction::AK_Insert, CA.Kind);
+ EXPECT_EQ("foo", CA.Text);
+
+ Comps.push_back(LineEditor::Completion("bar", "int bar()"));
+ LE->setListCompleter(TestListCompleter(Comps));
+ CA = LE->getCompletionAction("", 0);
+ EXPECT_EQ(LineEditor::CompletionAction::AK_ShowCompletions, CA.Kind);
+ ASSERT_EQ(2u, CA.Completions.size());
+ ASSERT_EQ("int foo()", CA.Completions[0]);
+ ASSERT_EQ("int bar()", CA.Completions[1]);
+
+ Comps.clear();
+ Comps.push_back(LineEditor::Completion("fee", "int fee()"));
+ Comps.push_back(LineEditor::Completion("fi", "int fi()"));
+ Comps.push_back(LineEditor::Completion("foe", "int foe()"));
+ Comps.push_back(LineEditor::Completion("fum", "int fum()"));
+ LE->setListCompleter(TestListCompleter(Comps));
+ CA = LE->getCompletionAction("", 0);
+ EXPECT_EQ(LineEditor::CompletionAction::AK_Insert, CA.Kind);
+ EXPECT_EQ("f", CA.Text);
+}
diff --git a/unittests/LineEditor/Makefile b/unittests/LineEditor/Makefile
new file mode 100644
index 000000000000..058b6e46eb93
--- /dev/null
+++ b/unittests/LineEditor/Makefile
@@ -0,0 +1,15 @@
+##===- unittests/LineEditor/Makefile -----------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TESTNAME = LineEditor
+LINK_COMPONENTS := lineeditor
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Linker/CMakeLists.txt b/unittests/Linker/CMakeLists.txt
new file mode 100644
index 000000000000..c3dccb6c7bb8
--- /dev/null
+++ b/unittests/Linker/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(LLVM_LINK_COMPONENTS
+ core
+ linker
+ )
+
+set(LinkerSources
+ LinkModulesTest.cpp
+ )
+
+add_llvm_unittest(LinkerTests
+ ${LinkerSources}
+ )
diff --git a/unittests/Linker/LinkModulesTest.cpp b/unittests/Linker/LinkModulesTest.cpp
new file mode 100644
index 000000000000..4ccced195d24
--- /dev/null
+++ b/unittests/Linker/LinkModulesTest.cpp
@@ -0,0 +1,156 @@
+//===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Linker/Linker.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class LinkModuleTest : public testing::Test {
+protected:
+ virtual void SetUp() {
+ M.reset(new Module("MyModule", Ctx));
+ FunctionType *FTy = FunctionType::get(
+ Type::getInt8PtrTy(Ctx), Type::getInt32Ty(Ctx), false /*=isVarArg*/);
+ F = Function::Create(FTy, Function::ExternalLinkage, "ba_func", M.get());
+ F->setCallingConv(CallingConv::C);
+
+ EntryBB = BasicBlock::Create(Ctx, "entry", F);
+ SwitchCase1BB = BasicBlock::Create(Ctx, "switch.case.1", F);
+ SwitchCase2BB = BasicBlock::Create(Ctx, "switch.case.2", F);
+ ExitBB = BasicBlock::Create(Ctx, "exit", F);
+
+ ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
+
+ GV = new GlobalVariable(*M.get(), AT, false /*=isConstant*/,
+ GlobalValue::InternalLinkage, nullptr,"switch.bas");
+
+ // Global Initializer
+ std::vector<Constant *> Init;
+ Constant *SwitchCase1BA = BlockAddress::get(SwitchCase1BB);
+ Init.push_back(SwitchCase1BA);
+
+ Constant *SwitchCase2BA = BlockAddress::get(SwitchCase2BB);
+ Init.push_back(SwitchCase2BA);
+
+ ConstantInt *One = ConstantInt::get(Type::getInt32Ty(Ctx), 1);
+ Constant *OnePtr = ConstantExpr::getCast(Instruction::IntToPtr, One,
+ Type::getInt8PtrTy(Ctx));
+ Init.push_back(OnePtr);
+
+ GV->setInitializer(ConstantArray::get(AT, Init));
+ }
+
+ virtual void TearDown() { M.reset(); }
+
+ LLVMContext Ctx;
+ std::unique_ptr<Module> M;
+ Function *F;
+ GlobalVariable *GV;
+ BasicBlock *EntryBB;
+ BasicBlock *SwitchCase1BB;
+ BasicBlock *SwitchCase2BB;
+ BasicBlock *ExitBB;
+};
+
+TEST_F(LinkModuleTest, BlockAddress) {
+ IRBuilder<> Builder(EntryBB);
+
+ std::vector<Value *> GEPIndices;
+ GEPIndices.push_back(ConstantInt::get(Type::getInt32Ty(Ctx), 0));
+ GEPIndices.push_back(F->arg_begin());
+
+ Value *GEP = Builder.CreateGEP(GV, GEPIndices, "switch.gep");
+ Value *Load = Builder.CreateLoad(GEP, "switch.load");
+
+ Builder.CreateRet(Load);
+
+ Builder.SetInsertPoint(SwitchCase1BB);
+ Builder.CreateBr(ExitBB);
+
+ Builder.SetInsertPoint(SwitchCase2BB);
+ Builder.CreateBr(ExitBB);
+
+ Builder.SetInsertPoint(ExitBB);
+ Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx)));
+
+ Module *LinkedModule = new Module("MyModuleLinked", Ctx);
+ Linker::LinkModules(LinkedModule, M.get(), Linker::PreserveSource, nullptr);
+
+ // Delete the original module.
+ M.reset();
+
+ // Check that the global "@switch.bas" is well-formed.
+ const GlobalVariable *LinkedGV = LinkedModule->getNamedGlobal("switch.bas");
+ const Constant *Init = LinkedGV->getInitializer();
+
+ // @switch.bas = internal global [3 x i8*]
+ // [i8* blockaddress(@ba_func, %switch.case.1),
+ // i8* blockaddress(@ba_func, %switch.case.2),
+ // i8* inttoptr (i32 1 to i8*)]
+
+ ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
+ EXPECT_EQ(AT, Init->getType());
+
+ Value *Elem = Init->getOperand(0);
+ ASSERT_TRUE(isa<BlockAddress>(Elem));
+ EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
+ LinkedModule->getFunction("ba_func"));
+ EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
+ LinkedModule->getFunction("ba_func"));
+
+ Elem = Init->getOperand(1);
+ ASSERT_TRUE(isa<BlockAddress>(Elem));
+ EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
+ LinkedModule->getFunction("ba_func"));
+ EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
+ LinkedModule->getFunction("ba_func"));
+
+ delete LinkedModule;
+}
+
+TEST_F(LinkModuleTest, EmptyModule) {
+ Module *InternalM = new Module("InternalModule", Ctx);
+ FunctionType *FTy = FunctionType::get(
+ Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false /*=isVarArgs*/);
+
+ F = Function::Create(FTy, Function::InternalLinkage, "bar", InternalM);
+ F->setCallingConv(CallingConv::C);
+
+ BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
+ IRBuilder<> Builder(BB);
+ Builder.CreateRetVoid();
+
+ StructType *STy = StructType::create(Ctx, PointerType::get(FTy, 0));
+
+ GlobalVariable *GV =
+ new GlobalVariable(*InternalM, STy, false /*=isConstant*/,
+ GlobalValue::InternalLinkage, nullptr, "g");
+
+ GV->setInitializer(ConstantStruct::get(STy, F));
+
+ Module *EmptyM = new Module("EmptyModule1", Ctx);
+ Linker::LinkModules(EmptyM, InternalM, Linker::PreserveSource, nullptr);
+
+ delete EmptyM;
+ EmptyM = new Module("EmptyModule2", Ctx);
+ Linker::LinkModules(InternalM, EmptyM, Linker::PreserveSource, nullptr);
+
+ delete EmptyM;
+ delete InternalM;
+}
+
+} // end anonymous namespace
diff --git a/unittests/Object/Makefile b/unittests/Linker/Makefile
index 9062149a24d9..c6058c4d60df 100644
--- a/unittests/Object/Makefile
+++ b/unittests/Linker/Makefile
@@ -1,4 +1,4 @@
-##===- unittests/Object/Makefile ---------------------------*- Makefile -*-===##
+##===- unittests/Linker/Makefile ---------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -8,8 +8,8 @@
##===----------------------------------------------------------------------===##
LEVEL = ../..
-TESTNAME = Object
-LINK_COMPONENTS := object
+TESTNAME = Linker
+LINK_COMPONENTS := core linker
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/MC/CMakeLists.txt b/unittests/MC/CMakeLists.txt
index 0e4782c83f40..37543f48bcef 100644
--- a/unittests/MC/CMakeLists.txt
+++ b/unittests/MC/CMakeLists.txt
@@ -1,11 +1,11 @@
set(LLVM_LINK_COMPONENTS
MC
- )
-
-set(MCSources
- MCAtomTest.cpp
+ MCAnalysis
+ Support
)
add_llvm_unittest(MCTests
- ${MCSources}
+ MCAtomTest.cpp
+ StringTableBuilderTest.cpp
+ YAMLTest.cpp
)
diff --git a/unittests/MC/MCAtomTest.cpp b/unittests/MC/MCAtomTest.cpp
index 17b056cd2dea..16228b521f42 100644
--- a/unittests/MC/MCAtomTest.cpp
+++ b/unittests/MC/MCAtomTest.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAtom.h"
-#include "llvm/MC/MCModule.h"
+#include "llvm/MC/MCAnalysis/MCAtom.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
#include "gtest/gtest.h"
namespace llvm {
diff --git a/unittests/MC/Makefile b/unittests/MC/Makefile
index 4c25697d28dc..07a608e65a34 100644
--- a/unittests/MC/Makefile
+++ b/unittests/MC/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TESTNAME = MC
-LINK_COMPONENTS := MC
+LINK_COMPONENTS := MCAnalysis
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/MC/StringTableBuilderTest.cpp b/unittests/MC/StringTableBuilderTest.cpp
new file mode 100644
index 000000000000..d30dc6222d23
--- /dev/null
+++ b/unittests/MC/StringTableBuilderTest.cpp
@@ -0,0 +1,40 @@
+//===----------- StringTableBuilderTest.cpp -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/StringTableBuilder.h"
+#include "gtest/gtest.h"
+#include <string>
+
+using namespace llvm;
+
+namespace {
+
+TEST(StringTableBuilderTest, Basic) {
+ StringTableBuilder B;
+
+ B.add("foo");
+ B.add("bar");
+ B.add("foobar");
+
+ B.finalize();
+
+ std::string Expected;
+ Expected += '\x00';
+ Expected += "foobar";
+ Expected += '\x00';
+ Expected += "foo";
+ Expected += '\x00';
+
+ EXPECT_EQ(Expected, B.data());
+ EXPECT_EQ(1U, B.getOffset("foobar"));
+ EXPECT_EQ(4U, B.getOffset("bar"));
+ EXPECT_EQ(8U, B.getOffset("foo"));
+}
+
+}
diff --git a/unittests/Object/YAMLTest.cpp b/unittests/MC/YAMLTest.cpp
index 3ae92ae1baea..09709ad73fc7 100644
--- a/unittests/Object/YAMLTest.cpp
+++ b/unittests/MC/YAMLTest.cpp
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Object/YAML.h"
+#include "llvm/MC/YAML.h"
#include "llvm/Support/YAMLTraits.h"
#include "gtest/gtest.h"
using namespace llvm;
struct BinaryHolder {
- object::yaml::BinaryRef Binary;
+ yaml::BinaryRef Binary;
};
namespace llvm {
@@ -34,5 +34,5 @@ TEST(ObjectYAML, BinaryRef) {
llvm::raw_svector_ostream OS(Buf);
yaml::Output YOut(OS);
YOut << BH;
- EXPECT_NE(OS.str().find("\"\""), StringRef::npos);
+ EXPECT_NE(OS.str().find("''"), StringRef::npos);
}
diff --git a/unittests/Makefile b/unittests/Makefile
index 06ba93243e38..603e7d58f8c7 100644
--- a/unittests/Makefile
+++ b/unittests/Makefile
@@ -10,9 +10,10 @@
LEVEL = ..
PARALLEL_DIRS = ADT Analysis Bitcode CodeGen DebugInfo ExecutionEngine IR \
- MC Object Option Support Transforms
+ LineEditor Linker MC Option Support Transforms
-include $(LEVEL)/Makefile.common
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
clean::
$(Verb) $(RM) -f *Tests
diff --git a/unittests/Makefile.unittest b/unittests/Makefile.unittest
index bd32aed4b0a2..a39edc675698 100644
--- a/unittests/Makefile.unittest
+++ b/unittests/Makefile.unittest
@@ -11,13 +11,23 @@
#
##===----------------------------------------------------------------------===##
-# Set up variables for building a unit test.
-ifdef TESTNAME
-
ifndef MAKEFILE_UNITTEST_NO_INCLUDE_COMMON
include $(LEVEL)/Makefile.common
endif
+# Clean up out-of-tree stray unittests for Lit not to pick one up.
+.PHONY: cleanup-local
+cleanup-local:
+ -$(Verb) $(FIND) $(filter-out $(PARALLEL_DIRS), $(wildcard *)) -type f \
+ -path '*/$(BuildMode)/*Tests$(EXEEXT)' \
+ -exec rm -f '{}' \;
+
+all:: cleanup-local
+clean:: cleanup-local
+
+# Set up variables for building a unit test.
+ifdef TESTNAME
+
LLVMUnitTestExe = $(BuildMode)/$(TESTNAME)Tests$(EXEEXT)
# Note that these flags are duplicated when building GoogleTest itself in
@@ -42,9 +52,6 @@ ifeq ($(ENABLE_SHARED), 1)
# we'll never install unittests.
LD.Flags += $(RPATH) -Wl,$(SharedLibDir)
endif
- # Also set {DYLD,LD}_LIBRARY_PATH because OSX ignores the rpath most
- # of the time.
- Run.Shared := $(SHLIBPATH_VAR)="$(SharedLibDir)$${$(SHLIBPATH_VAR):+:}$$$(SHLIBPATH_VAR)"
endif
$(LLVMUnitTestExe): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths)
@@ -57,6 +64,6 @@ $(LLVMUnitTestExe): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths)
all:: $(LLVMUnitTestExe)
unitcheck:: $(LLVMUnitTestExe)
- $(Run.Shared) $(LLVMUnitTestExe)
+ $(LLVMUnitTestExe)
endif
diff --git a/unittests/Object/CMakeLists.txt b/unittests/Object/CMakeLists.txt
deleted file mode 100644
index b491dd7f6bdf..000000000000
--- a/unittests/Object/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- object
- )
-
-add_llvm_unittest(ObjectTests
- YAMLTest.cpp
- )
diff --git a/unittests/Option/CMakeLists.txt b/unittests/Option/CMakeLists.txt
index 185d503912fd..07f7b91d5f5b 100644
--- a/unittests/Option/CMakeLists.txt
+++ b/unittests/Option/CMakeLists.txt
@@ -11,5 +11,3 @@ add_public_tablegen_target(OptsTestTableGen)
add_llvm_unittest(OptionTests
OptionParsingTest.cpp
)
-
-add_dependencies(OptionTests OptsTestTableGen)
diff --git a/unittests/Option/OptionParsingTest.cpp b/unittests/Option/OptionParsingTest.cpp
index 11d6d1e87ebb..aa32da3a595f 100644
--- a/unittests/Option/OptionParsingTest.cpp
+++ b/unittests/Option/OptionParsingTest.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
@@ -68,7 +67,8 @@ const char *Args[] = {
TEST(Option, OptionParsing) {
TestOptTable T;
unsigned MAI, MAC;
- OwningPtr<InputArgList> AL(T.ParseArgs(Args, array_endof(Args), MAI, MAC));
+ std::unique_ptr<InputArgList> AL(
+ T.ParseArgs(std::begin(Args), std::end(Args), MAI, MAC));
// Check they all exist.
EXPECT_TRUE(AL->hasArg(OPT_A));
@@ -111,10 +111,10 @@ TEST(Option, OptionParsing) {
TEST(Option, ParseWithFlagExclusions) {
TestOptTable T;
unsigned MAI, MAC;
- OwningPtr<InputArgList> AL;
+ std::unique_ptr<InputArgList> AL;
// Exclude flag3 to avoid parsing as OPT_SLASH_C.
- AL.reset(T.ParseArgs(Args, array_endof(Args), MAI, MAC,
+ AL.reset(T.ParseArgs(std::begin(Args), std::end(Args), MAI, MAC,
/*FlagsToInclude=*/0,
/*FlagsToExclude=*/OptFlag3));
EXPECT_TRUE(AL->hasArg(OPT_A));
@@ -122,7 +122,7 @@ TEST(Option, ParseWithFlagExclusions) {
EXPECT_FALSE(AL->hasArg(OPT_SLASH_C));
// Exclude flag1 to avoid parsing as OPT_C.
- AL.reset(T.ParseArgs(Args, array_endof(Args), MAI, MAC,
+ AL.reset(T.ParseArgs(std::begin(Args), std::end(Args), MAI, MAC,
/*FlagsToInclude=*/0,
/*FlagsToExclude=*/OptFlag1));
EXPECT_TRUE(AL->hasArg(OPT_B));
@@ -130,7 +130,7 @@ TEST(Option, ParseWithFlagExclusions) {
EXPECT_TRUE(AL->hasArg(OPT_SLASH_C));
const char *NewArgs[] = { "/C", "foo", "--C=bar" };
- AL.reset(T.ParseArgs(NewArgs, array_endof(NewArgs), MAI, MAC));
+ AL.reset(T.ParseArgs(std::begin(NewArgs), std::end(NewArgs), MAI, MAC));
EXPECT_TRUE(AL->hasArg(OPT_SLASH_C));
EXPECT_TRUE(AL->hasArg(OPT_C));
EXPECT_EQ(AL->getLastArgValue(OPT_SLASH_C), "foo");
@@ -142,7 +142,8 @@ TEST(Option, ParseAliasInGroup) {
unsigned MAI, MAC;
const char *MyArgs[] = { "-I" };
- OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
+ std::unique_ptr<InputArgList> AL(
+ T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
EXPECT_TRUE(AL->hasArg(OPT_H));
}
@@ -151,7 +152,8 @@ TEST(Option, AliasArgs) {
unsigned MAI, MAC;
const char *MyArgs[] = { "-J", "-Joo" };
- OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
+ std::unique_ptr<InputArgList> AL(
+ T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
EXPECT_TRUE(AL->hasArg(OPT_B));
EXPECT_EQ(AL->getAllArgValues(OPT_B)[0], "foo");
EXPECT_EQ(AL->getAllArgValues(OPT_B)[1], "bar");
@@ -162,7 +164,8 @@ TEST(Option, IgnoreCase) {
unsigned MAI, MAC;
const char *MyArgs[] = { "-a", "-joo" };
- OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
+ std::unique_ptr<InputArgList> AL(
+ T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
EXPECT_TRUE(AL->hasArg(OPT_A));
EXPECT_TRUE(AL->hasArg(OPT_B));
}
@@ -172,7 +175,8 @@ TEST(Option, DoNotIgnoreCase) {
unsigned MAI, MAC;
const char *MyArgs[] = { "-a", "-joo" };
- OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
+ std::unique_ptr<InputArgList> AL(
+ T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
EXPECT_FALSE(AL->hasArg(OPT_A));
EXPECT_FALSE(AL->hasArg(OPT_B));
}
@@ -182,7 +186,8 @@ TEST(Option, SlurpEmpty) {
unsigned MAI, MAC;
const char *MyArgs[] = { "-A", "-slurp" };
- OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
+ std::unique_ptr<InputArgList> AL(
+ T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
EXPECT_TRUE(AL->hasArg(OPT_A));
EXPECT_TRUE(AL->hasArg(OPT_Slurp));
EXPECT_EQ(AL->getAllArgValues(OPT_Slurp).size(), 0U);
@@ -193,7 +198,8 @@ TEST(Option, Slurp) {
unsigned MAI, MAC;
const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };
- OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
+ std::unique_ptr<InputArgList> AL(
+ T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
EXPECT_EQ(AL->size(), 2U);
EXPECT_TRUE(AL->hasArg(OPT_A));
EXPECT_FALSE(AL->hasArg(OPT_B));
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp
index cb9fa430369b..0fc84c7613f3 100644
--- a/unittests/Support/AllocatorTest.cpp
+++ b/unittests/Support/AllocatorTest.cpp
@@ -29,11 +29,26 @@ TEST(AllocatorTest, Basics) {
EXPECT_EQ(2, b[9]);
EXPECT_EQ(3, *c);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
+
+ BumpPtrAllocator Alloc2 = std::move(Alloc);
+ EXPECT_EQ(0U, Alloc.GetNumSlabs());
+ EXPECT_EQ(1U, Alloc2.GetNumSlabs());
+
+ // Make sure the old pointers still work. These are especially interesting
+ // under ASan or Valgrind.
+ EXPECT_EQ(1, *a);
+ EXPECT_EQ(2, b[0]);
+ EXPECT_EQ(2, b[9]);
+ EXPECT_EQ(3, *c);
+
+ Alloc = std::move(Alloc2);
+ EXPECT_EQ(0U, Alloc2.GetNumSlabs());
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
}
// Allocate enough bytes to create three slabs.
TEST(AllocatorTest, ThreeSlabs) {
- BumpPtrAllocator Alloc(4096, 4096);
+ BumpPtrAllocator Alloc;
Alloc.Allocate(3000, 0);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 0);
@@ -45,7 +60,7 @@ TEST(AllocatorTest, ThreeSlabs) {
// Allocate enough bytes to create two slabs, reset the allocator, and do it
// again.
TEST(AllocatorTest, TestReset) {
- BumpPtrAllocator Alloc(4096, 4096);
+ BumpPtrAllocator Alloc;
Alloc.Allocate(3000, 0);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 0);
@@ -81,10 +96,10 @@ TEST(AllocatorTest, TestAlignment) {
// Test allocating just over the slab size. This tests a bug where before the
// allocator incorrectly calculated the buffer end pointer.
TEST(AllocatorTest, TestOverflow) {
- BumpPtrAllocator Alloc(4096, 4096);
+ BumpPtrAllocator Alloc;
// Fill the slab right up until the end pointer.
- Alloc.Allocate(4096 - sizeof(MemSlab), 0);
+ Alloc.Allocate(4096, 0);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
// If we don't allocate a new slab, then we will have overflowed.
@@ -94,57 +109,60 @@ TEST(AllocatorTest, TestOverflow) {
// Test allocating with a size larger than the initial slab size.
TEST(AllocatorTest, TestSmallSlabSize) {
- BumpPtrAllocator Alloc(128);
+ BumpPtrAllocator Alloc;
- Alloc.Allocate(200, 0);
+ Alloc.Allocate(8000, 0);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
// Mock slab allocator that returns slabs aligned on 4096 bytes. There is no
// easy portable way to do this, so this is kind of a hack.
-class MockSlabAllocator : public SlabAllocator {
- MemSlab *LastSlab;
+class MockSlabAllocator {
+ static size_t LastSlabSize;
public:
- virtual ~MockSlabAllocator() { }
+ ~MockSlabAllocator() { }
- virtual MemSlab *Allocate(size_t Size) {
+ void *Allocate(size_t Size, size_t /*Alignment*/) {
// Allocate space for the alignment, the slab, and a void* that goes right
// before the slab.
size_t Alignment = 4096;
void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*));
- // Make the slab.
- MemSlab *Slab = (MemSlab*)(((uintptr_t)MemBase+sizeof(void*)+Alignment-1) &
- ~(uintptr_t)(Alignment - 1));
- Slab->Size = Size;
- Slab->NextPtr = 0;
+ // Find the slab start.
+ void *Slab = alignPtr((char *)MemBase + sizeof(void *), Alignment);
// Hold a pointer to the base so we can free the whole malloced block.
((void**)Slab)[-1] = MemBase;
- LastSlab = Slab;
+ LastSlabSize = Size;
return Slab;
}
- virtual void Deallocate(MemSlab *Slab) {
+ void Deallocate(void *Slab, size_t Size) {
free(((void**)Slab)[-1]);
}
- MemSlab *GetLastSlab() {
- return LastSlab;
- }
+ static size_t GetLastSlabSize() { return LastSlabSize; }
};
+size_t MockSlabAllocator::LastSlabSize = 0;
+
// Allocate a large-ish block with a really large alignment so that the
// allocator will think that it has space, but after it does the alignment it
// will not.
TEST(AllocatorTest, TestBigAlignment) {
- MockSlabAllocator SlabAlloc;
- BumpPtrAllocator Alloc(4096, 4096, SlabAlloc);
- uintptr_t Ptr = (uintptr_t)Alloc.Allocate(3000, 2048);
- MemSlab *Slab = SlabAlloc.GetLastSlab();
- EXPECT_LE(Ptr + 3000, ((uintptr_t)Slab) + Slab->Size);
+ BumpPtrAllocatorImpl<MockSlabAllocator> Alloc;
+
+ // First allocate a tiny bit to ensure we have to re-align things.
+ (void)Alloc.Allocate(1, 0);
+
+ // Now the big chunk with a big alignment.
+ (void)Alloc.Allocate(3000, 2048);
+
+ // We test that the last slab size is not the default 4096 byte slab, but
+ // rather a custom sized slab that is larger.
+ EXPECT_GT(MockSlabAllocator::GetLastSlabSize(), 4096u);
}
} // anonymous namespace
diff --git a/unittests/Support/BlockFrequencyTest.cpp b/unittests/Support/BlockFrequencyTest.cpp
index ffdea2c1790f..f6e3537de91a 100644
--- a/unittests/Support/BlockFrequencyTest.cpp
+++ b/unittests/Support/BlockFrequencyTest.cpp
@@ -15,9 +15,8 @@ TEST(BlockFrequencyTest, OneToZero) {
EXPECT_EQ(Freq.getFrequency(), 0u);
Freq = BlockFrequency(1);
- uint32_t Remainder = Freq.scale(Prob);
+ Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 0u);
- EXPECT_EQ(Remainder, UINT32_MAX - 1);
}
TEST(BlockFrequencyTest, OneToOne) {
@@ -27,9 +26,8 @@ TEST(BlockFrequencyTest, OneToOne) {
EXPECT_EQ(Freq.getFrequency(), 1u);
Freq = BlockFrequency(1);
- uint32_t Remainder = Freq.scale(Prob);
+ Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 1u);
- EXPECT_EQ(Remainder, 0u);
}
TEST(BlockFrequencyTest, ThreeToOne) {
@@ -39,9 +37,8 @@ TEST(BlockFrequencyTest, ThreeToOne) {
EXPECT_EQ(Freq.getFrequency(), 1u);
Freq = BlockFrequency(3);
- uint32_t Remainder = Freq.scale(Prob);
+ Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 1u);
- EXPECT_EQ(Remainder, 0u);
}
TEST(BlockFrequencyTest, MaxToHalfMax) {
@@ -51,9 +48,8 @@ TEST(BlockFrequencyTest, MaxToHalfMax) {
EXPECT_EQ(Freq.getFrequency(), 9223372034707292159ULL);
Freq = BlockFrequency(UINT64_MAX);
- uint32_t Remainder = Freq.scale(Prob);
+ Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 9223372034707292159ULL);
- EXPECT_EQ(Remainder, 0u);
}
TEST(BlockFrequencyTest, BigToBig) {
@@ -65,9 +61,8 @@ TEST(BlockFrequencyTest, BigToBig) {
EXPECT_EQ(Freq.getFrequency(), Big);
Freq = BlockFrequency(Big);
- uint32_t Remainder = Freq.scale(Prob);
+ Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), Big);
- EXPECT_EQ(Remainder, 0u);
}
TEST(BlockFrequencyTest, MaxToMax) {
@@ -80,109 +75,8 @@ TEST(BlockFrequencyTest, MaxToMax) {
// value, we do not signal saturation if the result equals said value, but
// saturating does not occur.
Freq = BlockFrequency(UINT64_MAX);
- uint32_t Remainder = Freq.scale(Prob);
+ Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
- EXPECT_EQ(Remainder, 0u);
-}
-
-TEST(BlockFrequencyTest, ScaleResultRemainderTest) {
- struct {
- uint64_t Freq;
- uint32_t Prob[2];
- uint64_t ExpectedFreq;
- uint32_t ExpectedRemainder;
- } Tests[80] = {
- // Data for scaling that results in <= 64 bit division.
- { 0x1423e2a50ULL, { 0x64819521, 0x7765dd13 }, 0x10f418889ULL, 0x92b9d25 },
- { 0x35ef14ceULL, { 0x28ade3c7, 0x304532ae }, 0x2d73c33aULL, 0x2c0fd0b6 },
- { 0xd03dbfbe24ULL, { 0x790079, 0xe419f3 }, 0x6e776fc1fdULL, 0x4a06dd },
- { 0x21d67410bULL, { 0x302a9dc2, 0x3ddb4442 }, 0x1a5948fd6ULL, 0x265d1c2a },
- { 0x8664aeadULL, { 0x3d523513, 0x403523b1 }, 0x805a04cfULL, 0x324c27b8 },
- { 0x201db0cf4ULL, { 0x35112a7b, 0x79fc0c74 }, 0xdf8b07f6ULL, 0x490c1dc4 },
- { 0x13f1e4430aULL, { 0x21c92bf, 0x21e63aae }, 0x13e0cba15ULL, 0x1df47c30 },
- { 0x16c83229ULL, { 0x3793f66f, 0x53180dea }, 0xf3ce7b6ULL, 0x1d0c1b6b },
- { 0xc62415be8ULL, { 0x9cc4a63, 0x4327ae9b }, 0x1ce8b71caULL, 0x3f2c696a },
- { 0x6fac5e434ULL, { 0xe5f9170, 0x1115e10b }, 0x5df23dd4cULL, 0x4dafc7c },
- { 0x1929375f2ULL, { 0x3a851375, 0x76c08456 }, 0xc662b082ULL, 0x343589ee },
- { 0x243c89db6ULL, { 0x354ebfc0, 0x450ef197 }, 0x1bf8c1661ULL, 0x4948e49 },
- { 0x310e9b31aULL, { 0x1b1b8acf, 0x2d3629f0 }, 0x1d69c93f9ULL, 0x73e3b96 },
- { 0xa1fae921dULL, { 0xa7a098c, 0x10469f44 }, 0x684413d6cULL, 0x86a882c },
- { 0xc1582d957ULL, { 0x498e061, 0x59856bc }, 0x9edc5f4e7ULL, 0x29b0653 },
- { 0x57cfee75ULL, { 0x1d061dc3, 0x7c8bfc17 }, 0x1476a220ULL, 0x2383d33f },
- { 0x139220080ULL, { 0x294a6c71, 0x2a2b07c9 }, 0x1329e1c76ULL, 0x7aa5da },
- { 0x1665d353cULL, { 0x7080db5, 0xde0d75c }, 0xb590d9fbULL, 0x7ba8c38 },
- { 0xe8f14541ULL, { 0x5188e8b2, 0x736527ef }, 0xa4971be5ULL, 0x6b612167 },
- { 0x2f4775f29ULL, { 0x254ef0fe, 0x435fcf50 }, 0x1a2e449c1ULL, 0x28bbf5e },
- { 0x27b85d8d7ULL, { 0x304c8220, 0x5de678f2 }, 0x146e3bef9ULL, 0x4b27097e },
- { 0x1d362e36bULL, { 0x36c85b12, 0x37a66f55 }, 0x1cc19b8e6ULL, 0x688e828 },
- { 0x155fd48c7ULL, { 0xf5894d, 0x1256108 }, 0x11e383602ULL, 0x111f0cb },
- { 0xb5db2d15ULL, { 0x39bb26c5, 0x5bdcda3e }, 0x72499259ULL, 0x59c4939b },
- { 0x153990298ULL, { 0x48921c09, 0x706eb817 }, 0xdb3268e8ULL, 0x66bb8a80 },
- { 0x28a7c3ed7ULL, { 0x1f776fd7, 0x349f7a70 }, 0x184f73ae1ULL, 0x28910321 },
- { 0x724dbeabULL, { 0x1bd149f5, 0x253a085e }, 0x5569c0b3ULL, 0xff8e2ed },
- { 0xd8f0c513ULL, { 0x18c8cc4c, 0x1b72bad0 }, 0xc3e30643ULL, 0xd85e134 },
- { 0x17ce3dcbULL, { 0x1e4c6260, 0x233b359e }, 0x1478f4afULL, 0x49ea31e },
- { 0x1ce036ce0ULL, { 0x29e3c8af, 0x5318dd4a }, 0xe8e76196ULL, 0x11d5b9c4 },
- { 0x1473ae2aULL, { 0x29b897ba, 0x2be29378 }, 0x13718185ULL, 0x6f93b2c },
- { 0x1dd41aa68ULL, { 0x3d0a4441, 0x5a0e8f12 }, 0x1437b6bbfULL, 0x54b09ffa },
- { 0x1b49e4a53ULL, { 0x3430c1fe, 0x5a204aed }, 0xfcd6852fULL, 0x15ad6ed7 },
- { 0x217941b19ULL, { 0x12ced2bd, 0x21b68310 }, 0x12aca65b1ULL, 0x1b2a9565 },
- { 0xac6a4dc8ULL, { 0x3ed68da8, 0x6fdca34c }, 0x60da926dULL, 0x22ff53e4 },
- { 0x1c503a4e7ULL, { 0xfcbbd32, 0x11e48d17 }, 0x18fec7d38ULL, 0xa8aa816 },
- { 0x1c885855ULL, { 0x213e919d, 0x25941897 }, 0x193de743ULL, 0x4ea09c },
- { 0x29b9c168eULL, { 0x2b644aea, 0x45725ee7 }, 0x1a122e5d5ULL, 0xbee1099 },
- { 0x806a33f2ULL, { 0x30a80a23, 0x5063733a }, 0x4db9a264ULL, 0x1eaed76e },
- { 0x282afc96bULL, { 0x143ae554, 0x1a9863ff }, 0x1e8de5204ULL, 0x158d9020 },
- // Data for scaling that results in > 64 bit division.
- { 0x23ca5f2f672ca41cULL, { 0xecbc641, 0x111373f7 }, 0x1f0301e5e8295ab5ULL, 0xf627f79 },
- { 0x5e4f2468142265e3ULL, { 0x1ddf5837, 0x32189233 }, 0x383ca7ba9fdd2c8cULL, 0x1c8f33e1 },
- { 0x277a1a6f6b266bf6ULL, { 0x415d81a8, 0x61eb5e1e }, 0x1a5a3e1d41b30c0fULL, 0x29cde3ae },
- { 0x1bdbb49a237035cbULL, { 0xea5bf17, 0x1d25ffb3 }, 0xdffc51c53d44b93ULL, 0x5170574 },
- { 0x2bce6d29b64fb8ULL, { 0x3bfd5631, 0x7525c9bb }, 0x166ebedda7ac57ULL, 0x3026dfab },
- { 0x3a02116103df5013ULL, { 0x2ee18a83, 0x3299aea8 }, 0x35be8922ab1e2a84ULL, 0x298d9919 },
- { 0x7b5762390799b18cULL, { 0x12f8e5b9, 0x2563bcd4 }, 0x3e960077aca01209ULL, 0x93afeb8 },
- { 0x69cfd72537021579ULL, { 0x4c35f468, 0x6a40feee }, 0x4be4cb3848be98a3ULL, 0x4ff96b9e },
- { 0x49dfdf835120f1c1ULL, { 0x8cb3759, 0x559eb891 }, 0x79663f7120edadeULL, 0x51b1fb5b },
- { 0x74b5be5c27676381ULL, { 0x47e4c5e0, 0x7c7b19ff }, 0x4367d2dff36a1028ULL, 0x7a7b5608 },
- { 0x4f50f97075e7f431ULL, { 0x9a50a17, 0x11cd1185 }, 0x2af952b34c032df4ULL, 0xfddc6a3 },
- { 0x2f8b0d712e393be4ULL, { 0x1487e386, 0x15aa356e }, 0x2d0df36478a776aaULL, 0x14e2564c },
- { 0x224c1c75999d3deULL, { 0x3b2df0ea, 0x4523b100 }, 0x1d5b481d145f08aULL, 0x15145eec },
- { 0x2bcbcea22a399a76ULL, { 0x28b58212, 0x48dd013e }, 0x187814d084c47cabULL, 0x3a38ebe2 },
- { 0x1dbfca91257cb2d1ULL, { 0x1a8c04d9, 0x5e92502c }, 0x859cf7d00f77545ULL, 0x7431f4d },
- { 0x7f20039b57cda935ULL, { 0xeccf651, 0x323f476e }, 0x25720cd976461a77ULL, 0x202817a3 },
- { 0x40512c6a586aa087ULL, { 0x113b0423, 0x398c9eab }, 0x1341c03de8696a7eULL, 0x1e27284b },
- { 0x63d802693f050a11ULL, { 0xf50cdd6, 0xfce2a44 }, 0x60c0177bb5e46846ULL, 0xf7ad89e },
- { 0x2d956b422838de77ULL, { 0xb2d345b, 0x1321e557 }, 0x1aa0ed16b6aa5319ULL, 0xfe1a5ce },
- { 0x5a1cdf0c1657bc91ULL, { 0x1d77bb0c, 0x1f991ff1 }, 0x54097ee94ff87560ULL, 0x11c4a26c },
- { 0x3801b26d7e00176bULL, { 0xeed25da, 0x1a819d8b }, 0x1f89e96a3a639526ULL, 0xcd51e7c },
- { 0x37655e74338e1e45ULL, { 0x300e170a, 0x5a1595fe }, 0x1d8cfb55fddc0441ULL, 0x3df05434 },
- { 0x7b38703f2a84e6ULL, { 0x66d9053, 0xc79b6b9 }, 0x3f7d4c91774094ULL, 0x26d939e },
- { 0x2245063c0acb3215ULL, { 0x30ce2f5b, 0x610e7271 }, 0x113b916468389235ULL, 0x1b588512 },
- { 0x6bc195877b7b8a7eULL, { 0x392004aa, 0x4a24e60c }, 0x530594fb17db6ba5ULL, 0x35c0a5f0 },
- { 0x40a3fde23c7b43dbULL, { 0x4e712195, 0x6553e56e }, 0x320a799bc76a466aULL, 0x5e23a5eb },
- { 0x1d3dfc2866fbccbaULL, { 0x5075b517, 0x5fc42245 }, 0x18917f0061595bc3ULL, 0x3fcf4527 },
- { 0x19aeb14045a61121ULL, { 0x1bf6edec, 0x707e2f4b }, 0x6626672a070bcc7ULL, 0x3607801f },
- { 0x44ff90486c531e9fULL, { 0x66598a, 0x8a90dc }, 0x32f6f2b0525199b0ULL, 0x5ab576 },
- { 0x3f3e7121092c5bcbULL, { 0x1c754df7, 0x5951a1b9 }, 0x14267f50b7ef375dULL, 0x221220a8 },
- { 0x60e2dafb7e50a67eULL, { 0x4d96c66e, 0x65bd878d }, 0x49e31715ac393f8bULL, 0x4e97b195 },
- { 0x656286667e0e6e29ULL, { 0x9d971a2, 0xacda23b }, 0x5c6ee315ead6cb4fULL, 0x516f5bd },
- { 0x1114e0974255d507ULL, { 0x1c693, 0x2d6ff }, 0xaae42e4b35f6e60ULL, 0x8b65 },
- { 0x508c8baf3a70ff5aULL, { 0x3b26b779, 0x6ad78745 }, 0x2c98387636c4b365ULL, 0x11dc6a51 },
- { 0x5b47bc666bf1f9cfULL, { 0x10a87ed6, 0x187d358a }, 0x3e1767155848368bULL, 0xfb871c },
- { 0x50954e3744460395ULL, { 0x7a42263, 0xcdaa048 }, 0x2fe739f0aee1fee1ULL, 0xb8add57 },
- { 0x20020b406550dd8fULL, { 0x3318539, 0x42eead0 }, 0x186f326325fa346bULL, 0x10d3ae7 },
- { 0x5bcb0b872439ffd5ULL, { 0x6f61fb2, 0x9af7344 }, 0x41fa1e3bec3c1b30ULL, 0x4fee45a },
- { 0x7a670f365db87a53ULL, { 0x417e102, 0x3bb54c67 }, 0x8642a558304fd9eULL, 0x3b65f514 },
- { 0x1ef0db1e7bab1cd0ULL, { 0x2b60cf38, 0x4188f78f }, 0x147ae0d6226b2ee6ULL, 0x336b6106 }
- };
-
- for (unsigned i = 0; i < 80; i++) {
- BlockFrequency Freq(Tests[i].Freq);
- uint32_t Remainder = Freq.scale(BranchProbability(Tests[i].Prob[0],
- Tests[i].Prob[1]));
- EXPECT_EQ(Tests[i].ExpectedFreq, Freq.getFrequency());
- EXPECT_EQ(Tests[i].ExpectedRemainder, Remainder);
- }
}
TEST(BlockFrequency, Divide) {
@@ -208,33 +102,12 @@ TEST(BlockFrequencyTest, Saturate) {
EXPECT_EQ(33506781356485509ULL, Freq.getFrequency());
}
-TEST(BlockFrequencyTest, ProbabilityCompare) {
- BranchProbability A(4, 5);
- BranchProbability B(4U << 29, 5U << 29);
- BranchProbability C(3, 4);
-
- EXPECT_TRUE(A == B);
- EXPECT_FALSE(A != B);
- EXPECT_FALSE(A < B);
- EXPECT_FALSE(A > B);
- EXPECT_TRUE(A <= B);
- EXPECT_TRUE(A >= B);
-
- EXPECT_FALSE(B == C);
- EXPECT_TRUE(B != C);
- EXPECT_FALSE(B < C);
- EXPECT_TRUE(B > C);
- EXPECT_FALSE(B <= C);
- EXPECT_TRUE(B >= C);
-
- BranchProbability BigZero(0, UINT32_MAX);
- BranchProbability BigOne(UINT32_MAX, UINT32_MAX);
- EXPECT_FALSE(BigZero == BigOne);
- EXPECT_TRUE(BigZero != BigOne);
- EXPECT_TRUE(BigZero < BigOne);
- EXPECT_FALSE(BigZero > BigOne);
- EXPECT_TRUE(BigZero <= BigOne);
- EXPECT_FALSE(BigZero >= BigOne);
+TEST(BlockFrequencyTest, SaturatingRightShift) {
+ BlockFrequency Freq(0x10080ULL);
+ Freq >>= 2;
+ EXPECT_EQ(Freq.getFrequency(), 0x4020ULL);
+ Freq >>= 20;
+ EXPECT_EQ(Freq.getFrequency(), 0x1ULL);
}
}
diff --git a/unittests/Support/BranchProbabilityTest.cpp b/unittests/Support/BranchProbabilityTest.cpp
new file mode 100644
index 000000000000..bbd4d4eba1c0
--- /dev/null
+++ b/unittests/Support/BranchProbabilityTest.cpp
@@ -0,0 +1,282 @@
+//===- unittest/Support/BranchProbabilityTest.cpp - BranchProbability tests -=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace llvm {
+void PrintTo(const BranchProbability &P, ::std::ostream *os) {
+ *os << P.getNumerator() << "/" << P.getDenominator();
+}
+}
+namespace {
+
+typedef BranchProbability BP;
+TEST(BranchProbabilityTest, Accessors) {
+ EXPECT_EQ(1u, BP(1, 7).getNumerator());
+ EXPECT_EQ(7u, BP(1, 7).getDenominator());
+ EXPECT_EQ(0u, BP::getZero().getNumerator());
+ EXPECT_EQ(1u, BP::getZero().getDenominator());
+ EXPECT_EQ(1u, BP::getOne().getNumerator());
+ EXPECT_EQ(1u, BP::getOne().getDenominator());
+}
+
+TEST(BranchProbabilityTest, Operators) {
+ EXPECT_TRUE(BP(1, 7) < BP(2, 7));
+ EXPECT_TRUE(BP(1, 7) < BP(1, 4));
+ EXPECT_TRUE(BP(5, 7) < BP(3, 4));
+ EXPECT_FALSE(BP(1, 7) < BP(1, 7));
+ EXPECT_FALSE(BP(1, 7) < BP(2, 14));
+ EXPECT_FALSE(BP(4, 7) < BP(1, 2));
+ EXPECT_FALSE(BP(4, 7) < BP(3, 7));
+
+ EXPECT_FALSE(BP(1, 7) > BP(2, 7));
+ EXPECT_FALSE(BP(1, 7) > BP(1, 4));
+ EXPECT_FALSE(BP(5, 7) > BP(3, 4));
+ EXPECT_FALSE(BP(1, 7) > BP(1, 7));
+ EXPECT_FALSE(BP(1, 7) > BP(2, 14));
+ EXPECT_TRUE(BP(4, 7) > BP(1, 2));
+ EXPECT_TRUE(BP(4, 7) > BP(3, 7));
+
+ EXPECT_TRUE(BP(1, 7) <= BP(2, 7));
+ EXPECT_TRUE(BP(1, 7) <= BP(1, 4));
+ EXPECT_TRUE(BP(5, 7) <= BP(3, 4));
+ EXPECT_TRUE(BP(1, 7) <= BP(1, 7));
+ EXPECT_TRUE(BP(1, 7) <= BP(2, 14));
+ EXPECT_FALSE(BP(4, 7) <= BP(1, 2));
+ EXPECT_FALSE(BP(4, 7) <= BP(3, 7));
+
+ EXPECT_FALSE(BP(1, 7) >= BP(2, 7));
+ EXPECT_FALSE(BP(1, 7) >= BP(1, 4));
+ EXPECT_FALSE(BP(5, 7) >= BP(3, 4));
+ EXPECT_TRUE(BP(1, 7) >= BP(1, 7));
+ EXPECT_TRUE(BP(1, 7) >= BP(2, 14));
+ EXPECT_TRUE(BP(4, 7) >= BP(1, 2));
+ EXPECT_TRUE(BP(4, 7) >= BP(3, 7));
+
+ EXPECT_FALSE(BP(1, 7) == BP(2, 7));
+ EXPECT_FALSE(BP(1, 7) == BP(1, 4));
+ EXPECT_FALSE(BP(5, 7) == BP(3, 4));
+ EXPECT_TRUE(BP(1, 7) == BP(1, 7));
+ EXPECT_TRUE(BP(1, 7) == BP(2, 14));
+ EXPECT_FALSE(BP(4, 7) == BP(1, 2));
+ EXPECT_FALSE(BP(4, 7) == BP(3, 7));
+
+ EXPECT_TRUE(BP(1, 7) != BP(2, 7));
+ EXPECT_TRUE(BP(1, 7) != BP(1, 4));
+ EXPECT_TRUE(BP(5, 7) != BP(3, 4));
+ EXPECT_FALSE(BP(1, 7) != BP(1, 7));
+ EXPECT_FALSE(BP(1, 7) != BP(2, 14));
+ EXPECT_TRUE(BP(4, 7) != BP(1, 2));
+ EXPECT_TRUE(BP(4, 7) != BP(3, 7));
+}
+
+TEST(BranchProbabilityTest, MoreOperators) {
+ BP A(4, 5);
+ BP B(4U << 29, 5U << 29);
+ BP C(3, 4);
+
+ EXPECT_TRUE(A == B);
+ EXPECT_FALSE(A != B);
+ EXPECT_FALSE(A < B);
+ EXPECT_FALSE(A > B);
+ EXPECT_TRUE(A <= B);
+ EXPECT_TRUE(A >= B);
+
+ EXPECT_FALSE(B == C);
+ EXPECT_TRUE(B != C);
+ EXPECT_FALSE(B < C);
+ EXPECT_TRUE(B > C);
+ EXPECT_FALSE(B <= C);
+ EXPECT_TRUE(B >= C);
+
+ BP BigZero(0, UINT32_MAX);
+ BP BigOne(UINT32_MAX, UINT32_MAX);
+ EXPECT_FALSE(BigZero == BigOne);
+ EXPECT_TRUE(BigZero != BigOne);
+ EXPECT_TRUE(BigZero < BigOne);
+ EXPECT_FALSE(BigZero > BigOne);
+ EXPECT_TRUE(BigZero <= BigOne);
+ EXPECT_FALSE(BigZero >= BigOne);
+}
+
+TEST(BranchProbabilityTest, getCompl) {
+ EXPECT_EQ(BP(5, 7), BP(2, 7).getCompl());
+ EXPECT_EQ(BP(2, 7), BP(5, 7).getCompl());
+ EXPECT_EQ(BP::getZero(), BP(7, 7).getCompl());
+ EXPECT_EQ(BP::getOne(), BP(0, 7).getCompl());
+}
+
+TEST(BranchProbabilityTest, scale) {
+ // Multiply by 1.0.
+ EXPECT_EQ(UINT64_MAX, BP(1, 1).scale(UINT64_MAX));
+ EXPECT_EQ(UINT64_MAX, BP(7, 7).scale(UINT64_MAX));
+ EXPECT_EQ(UINT32_MAX, BP(1, 1).scale(UINT32_MAX));
+ EXPECT_EQ(UINT32_MAX, BP(7, 7).scale(UINT32_MAX));
+ EXPECT_EQ(0u, BP(1, 1).scale(0));
+ EXPECT_EQ(0u, BP(7, 7).scale(0));
+
+ // Multiply by 0.0.
+ EXPECT_EQ(0u, BP(0, 1).scale(UINT64_MAX));
+ EXPECT_EQ(0u, BP(0, 1).scale(UINT64_MAX));
+ EXPECT_EQ(0u, BP(0, 1).scale(0));
+
+ auto Two63 = UINT64_C(1) << 63;
+ auto Two31 = UINT64_C(1) << 31;
+
+ // Multiply by 0.5.
+ EXPECT_EQ(Two63 - 1, BP(1, 2).scale(UINT64_MAX));
+
+ // Big fractions.
+ EXPECT_EQ(1u, BP(Two31, UINT32_MAX).scale(2));
+ EXPECT_EQ(Two31, BP(Two31, UINT32_MAX).scale(Two31 * 2));
+ EXPECT_EQ(Two63 + Two31, BP(Two31, UINT32_MAX).scale(UINT64_MAX));
+
+ // High precision.
+ EXPECT_EQ(UINT64_C(9223372047592194055),
+ BP(Two31 + 1, UINT32_MAX - 2).scale(UINT64_MAX));
+}
+
+TEST(BranchProbabilityTest, scaleByInverse) {
+ // Divide by 1.0.
+ EXPECT_EQ(UINT64_MAX, BP(1, 1).scaleByInverse(UINT64_MAX));
+ EXPECT_EQ(UINT64_MAX, BP(7, 7).scaleByInverse(UINT64_MAX));
+ EXPECT_EQ(UINT32_MAX, BP(1, 1).scaleByInverse(UINT32_MAX));
+ EXPECT_EQ(UINT32_MAX, BP(7, 7).scaleByInverse(UINT32_MAX));
+ EXPECT_EQ(0u, BP(1, 1).scaleByInverse(0));
+ EXPECT_EQ(0u, BP(7, 7).scaleByInverse(0));
+
+ // Divide by something very small.
+ EXPECT_EQ(UINT64_MAX, BP(1, UINT32_MAX).scaleByInverse(UINT64_MAX));
+ EXPECT_EQ(uint64_t(UINT32_MAX) * UINT32_MAX,
+ BP(1, UINT32_MAX).scaleByInverse(UINT32_MAX));
+ EXPECT_EQ(UINT32_MAX, BP(1, UINT32_MAX).scaleByInverse(1));
+
+ auto Two63 = UINT64_C(1) << 63;
+ auto Two31 = UINT64_C(1) << 31;
+
+ // Divide by 0.5.
+ EXPECT_EQ(UINT64_MAX - 1, BP(1, 2).scaleByInverse(Two63 - 1));
+ EXPECT_EQ(UINT64_MAX, BP(1, 2).scaleByInverse(Two63));
+
+ // Big fractions.
+ EXPECT_EQ(1u, BP(Two31, UINT32_MAX).scaleByInverse(1));
+ EXPECT_EQ(2u, BP(Two31 - 1, UINT32_MAX).scaleByInverse(1));
+ EXPECT_EQ(Two31 * 2 - 1, BP(Two31, UINT32_MAX).scaleByInverse(Two31));
+ EXPECT_EQ(Two31 * 2 + 1, BP(Two31 - 1, UINT32_MAX).scaleByInverse(Two31));
+ EXPECT_EQ(UINT64_MAX, BP(Two31, UINT32_MAX).scaleByInverse(Two63 + Two31));
+
+ // High precision. The exact answers to these are close to the successors of
+ // the floor. If we were rounding, these would round up.
+ EXPECT_EQ(UINT64_C(18446744065119617030),
+ BP(Two31 + 2, UINT32_MAX - 2)
+ .scaleByInverse(UINT64_C(9223372047592194055)));
+ EXPECT_EQ(UINT64_C(18446744065119617026),
+ BP(Two31 + 1, UINT32_MAX).scaleByInverse(Two63 + Two31));
+}
+
+TEST(BranchProbabilityTest, scaleBruteForce) {
+ struct {
+ uint64_t Num;
+ uint32_t Prob[2];
+ uint64_t Result;
+ } Tests[] = {
+ // Data for scaling that results in <= 64 bit division.
+ { 0x1423e2a50ULL, { 0x64819521, 0x7765dd13 }, 0x10f418889ULL },
+ { 0x35ef14ceULL, { 0x28ade3c7, 0x304532ae }, 0x2d73c33aULL },
+ { 0xd03dbfbe24ULL, { 0x790079, 0xe419f3 }, 0x6e776fc1fdULL },
+ { 0x21d67410bULL, { 0x302a9dc2, 0x3ddb4442 }, 0x1a5948fd6ULL },
+ { 0x8664aeadULL, { 0x3d523513, 0x403523b1 }, 0x805a04cfULL },
+ { 0x201db0cf4ULL, { 0x35112a7b, 0x79fc0c74 }, 0xdf8b07f6ULL },
+ { 0x13f1e4430aULL, { 0x21c92bf, 0x21e63aae }, 0x13e0cba15ULL },
+ { 0x16c83229ULL, { 0x3793f66f, 0x53180dea }, 0xf3ce7b6ULL },
+ { 0xc62415be8ULL, { 0x9cc4a63, 0x4327ae9b }, 0x1ce8b71caULL },
+ { 0x6fac5e434ULL, { 0xe5f9170, 0x1115e10b }, 0x5df23dd4cULL },
+ { 0x1929375f2ULL, { 0x3a851375, 0x76c08456 }, 0xc662b082ULL },
+ { 0x243c89db6ULL, { 0x354ebfc0, 0x450ef197 }, 0x1bf8c1661ULL },
+ { 0x310e9b31aULL, { 0x1b1b8acf, 0x2d3629f0 }, 0x1d69c93f9ULL },
+ { 0xa1fae921dULL, { 0xa7a098c, 0x10469f44 }, 0x684413d6cULL },
+ { 0xc1582d957ULL, { 0x498e061, 0x59856bc }, 0x9edc5f4e7ULL },
+ { 0x57cfee75ULL, { 0x1d061dc3, 0x7c8bfc17 }, 0x1476a220ULL },
+ { 0x139220080ULL, { 0x294a6c71, 0x2a2b07c9 }, 0x1329e1c76ULL },
+ { 0x1665d353cULL, { 0x7080db5, 0xde0d75c }, 0xb590d9fbULL },
+ { 0xe8f14541ULL, { 0x5188e8b2, 0x736527ef }, 0xa4971be5ULL },
+ { 0x2f4775f29ULL, { 0x254ef0fe, 0x435fcf50 }, 0x1a2e449c1ULL },
+ { 0x27b85d8d7ULL, { 0x304c8220, 0x5de678f2 }, 0x146e3bef9ULL },
+ { 0x1d362e36bULL, { 0x36c85b12, 0x37a66f55 }, 0x1cc19b8e6ULL },
+ { 0x155fd48c7ULL, { 0xf5894d, 0x1256108 }, 0x11e383602ULL },
+ { 0xb5db2d15ULL, { 0x39bb26c5, 0x5bdcda3e }, 0x72499259ULL },
+ { 0x153990298ULL, { 0x48921c09, 0x706eb817 }, 0xdb3268e8ULL },
+ { 0x28a7c3ed7ULL, { 0x1f776fd7, 0x349f7a70 }, 0x184f73ae1ULL },
+ { 0x724dbeabULL, { 0x1bd149f5, 0x253a085e }, 0x5569c0b3ULL },
+ { 0xd8f0c513ULL, { 0x18c8cc4c, 0x1b72bad0 }, 0xc3e30643ULL },
+ { 0x17ce3dcbULL, { 0x1e4c6260, 0x233b359e }, 0x1478f4afULL },
+ { 0x1ce036ce0ULL, { 0x29e3c8af, 0x5318dd4a }, 0xe8e76196ULL },
+ { 0x1473ae2aULL, { 0x29b897ba, 0x2be29378 }, 0x13718185ULL },
+ { 0x1dd41aa68ULL, { 0x3d0a4441, 0x5a0e8f12 }, 0x1437b6bbfULL },
+ { 0x1b49e4a53ULL, { 0x3430c1fe, 0x5a204aed }, 0xfcd6852fULL },
+ { 0x217941b19ULL, { 0x12ced2bd, 0x21b68310 }, 0x12aca65b1ULL },
+ { 0xac6a4dc8ULL, { 0x3ed68da8, 0x6fdca34c }, 0x60da926dULL },
+ { 0x1c503a4e7ULL, { 0xfcbbd32, 0x11e48d17 }, 0x18fec7d38ULL },
+ { 0x1c885855ULL, { 0x213e919d, 0x25941897 }, 0x193de743ULL },
+ { 0x29b9c168eULL, { 0x2b644aea, 0x45725ee7 }, 0x1a122e5d5ULL },
+ { 0x806a33f2ULL, { 0x30a80a23, 0x5063733a }, 0x4db9a264ULL },
+ { 0x282afc96bULL, { 0x143ae554, 0x1a9863ff }, 0x1e8de5204ULL },
+ // Data for scaling that results in > 64 bit division.
+ { 0x23ca5f2f672ca41cULL, { 0xecbc641, 0x111373f7 }, 0x1f0301e5e8295ab5ULL },
+ { 0x5e4f2468142265e3ULL, { 0x1ddf5837, 0x32189233 }, 0x383ca7ba9fdd2c8cULL },
+ { 0x277a1a6f6b266bf6ULL, { 0x415d81a8, 0x61eb5e1e }, 0x1a5a3e1d41b30c0fULL },
+ { 0x1bdbb49a237035cbULL, { 0xea5bf17, 0x1d25ffb3 }, 0xdffc51c53d44b93ULL },
+ { 0x2bce6d29b64fb8ULL, { 0x3bfd5631, 0x7525c9bb }, 0x166ebedda7ac57ULL },
+ { 0x3a02116103df5013ULL, { 0x2ee18a83, 0x3299aea8 }, 0x35be8922ab1e2a84ULL },
+ { 0x7b5762390799b18cULL, { 0x12f8e5b9, 0x2563bcd4 }, 0x3e960077aca01209ULL },
+ { 0x69cfd72537021579ULL, { 0x4c35f468, 0x6a40feee }, 0x4be4cb3848be98a3ULL },
+ { 0x49dfdf835120f1c1ULL, { 0x8cb3759, 0x559eb891 }, 0x79663f7120edadeULL },
+ { 0x74b5be5c27676381ULL, { 0x47e4c5e0, 0x7c7b19ff }, 0x4367d2dff36a1028ULL },
+ { 0x4f50f97075e7f431ULL, { 0x9a50a17, 0x11cd1185 }, 0x2af952b34c032df4ULL },
+ { 0x2f8b0d712e393be4ULL, { 0x1487e386, 0x15aa356e }, 0x2d0df36478a776aaULL },
+ { 0x224c1c75999d3deULL, { 0x3b2df0ea, 0x4523b100 }, 0x1d5b481d145f08aULL },
+ { 0x2bcbcea22a399a76ULL, { 0x28b58212, 0x48dd013e }, 0x187814d084c47cabULL },
+ { 0x1dbfca91257cb2d1ULL, { 0x1a8c04d9, 0x5e92502c }, 0x859cf7d00f77545ULL },
+ { 0x7f20039b57cda935ULL, { 0xeccf651, 0x323f476e }, 0x25720cd976461a77ULL },
+ { 0x40512c6a586aa087ULL, { 0x113b0423, 0x398c9eab }, 0x1341c03de8696a7eULL },
+ { 0x63d802693f050a11ULL, { 0xf50cdd6, 0xfce2a44 }, 0x60c0177bb5e46846ULL },
+ { 0x2d956b422838de77ULL, { 0xb2d345b, 0x1321e557 }, 0x1aa0ed16b6aa5319ULL },
+ { 0x5a1cdf0c1657bc91ULL, { 0x1d77bb0c, 0x1f991ff1 }, 0x54097ee94ff87560ULL },
+ { 0x3801b26d7e00176bULL, { 0xeed25da, 0x1a819d8b }, 0x1f89e96a3a639526ULL },
+ { 0x37655e74338e1e45ULL, { 0x300e170a, 0x5a1595fe }, 0x1d8cfb55fddc0441ULL },
+ { 0x7b38703f2a84e6ULL, { 0x66d9053, 0xc79b6b9 }, 0x3f7d4c91774094ULL },
+ { 0x2245063c0acb3215ULL, { 0x30ce2f5b, 0x610e7271 }, 0x113b916468389235ULL },
+ { 0x6bc195877b7b8a7eULL, { 0x392004aa, 0x4a24e60c }, 0x530594fb17db6ba5ULL },
+ { 0x40a3fde23c7b43dbULL, { 0x4e712195, 0x6553e56e }, 0x320a799bc76a466aULL },
+ { 0x1d3dfc2866fbccbaULL, { 0x5075b517, 0x5fc42245 }, 0x18917f0061595bc3ULL },
+ { 0x19aeb14045a61121ULL, { 0x1bf6edec, 0x707e2f4b }, 0x6626672a070bcc7ULL },
+ { 0x44ff90486c531e9fULL, { 0x66598a, 0x8a90dc }, 0x32f6f2b0525199b0ULL },
+ { 0x3f3e7121092c5bcbULL, { 0x1c754df7, 0x5951a1b9 }, 0x14267f50b7ef375dULL },
+ { 0x60e2dafb7e50a67eULL, { 0x4d96c66e, 0x65bd878d }, 0x49e31715ac393f8bULL },
+ { 0x656286667e0e6e29ULL, { 0x9d971a2, 0xacda23b }, 0x5c6ee315ead6cb4fULL },
+ { 0x1114e0974255d507ULL, { 0x1c693, 0x2d6ff }, 0xaae42e4b35f6e60ULL },
+ { 0x508c8baf3a70ff5aULL, { 0x3b26b779, 0x6ad78745 }, 0x2c98387636c4b365ULL },
+ { 0x5b47bc666bf1f9cfULL, { 0x10a87ed6, 0x187d358a }, 0x3e1767155848368bULL },
+ { 0x50954e3744460395ULL, { 0x7a42263, 0xcdaa048 }, 0x2fe739f0aee1fee1ULL },
+ { 0x20020b406550dd8fULL, { 0x3318539, 0x42eead0 }, 0x186f326325fa346bULL },
+ { 0x5bcb0b872439ffd5ULL, { 0x6f61fb2, 0x9af7344 }, 0x41fa1e3bec3c1b30ULL },
+ { 0x7a670f365db87a53ULL, { 0x417e102, 0x3bb54c67 }, 0x8642a558304fd9eULL },
+ { 0x1ef0db1e7bab1cd0ULL, { 0x2b60cf38, 0x4188f78f }, 0x147ae0d6226b2ee6ULL }
+ };
+
+ for (const auto &T : Tests) {
+ EXPECT_EQ(T.Result, BP(T.Prob[0], T.Prob[1]).scale(T.Num));
+ }
+}
+
+}
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt
index 0abc2ffe1d9c..97c5c43aeb6e 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -1,6 +1,5 @@
set(LLVM_LINK_COMPONENTS
Support
- Core
)
add_llvm_unittest(SupportTests
@@ -8,32 +7,36 @@ add_llvm_unittest(SupportTests
AllocatorTest.cpp
ArrayRecyclerTest.cpp
BlockFrequencyTest.cpp
+ BranchProbabilityTest.cpp
Casting.cpp
CommandLineTest.cpp
CompressionTest.cpp
- ConstantRangeTest.cpp
ConvertUTFTest.cpp
DataExtractorTest.cpp
EndianTest.cpp
ErrorOrTest.cpp
FileOutputBufferTest.cpp
- LeakDetectorTest.cpp
+ IteratorTest.cpp
+ LEB128Test.cpp
+ LineIteratorTest.cpp
LockFileManagerTest.cpp
+ MD5Test.cpp
ManagedStatic.cpp
MathExtrasTest.cpp
- MD5Test.cpp
MemoryBufferTest.cpp
MemoryTest.cpp
Path.cpp
ProcessTest.cpp
ProgramTest.cpp
RegexTest.cpp
+ ScaledNumberTest.cpp
SourceMgrTest.cpp
+ SpecialCaseListTest.cpp
+ StringPool.cpp
SwapByteOrderTest.cpp
ThreadLocalTest.cpp
TimeValueTest.cpp
UnicodeTest.cpp
- ValueHandleTest.cpp
YAMLIOTest.cpp
YAMLParserTest.cpp
formatted_raw_ostream_test.cpp
diff --git a/unittests/Support/Casting.cpp b/unittests/Support/Casting.cpp
index 362abeecd07a..88c7d19aa464 100644
--- a/unittests/Support/Casting.cpp
+++ b/unittests/Support/Casting.cpp
@@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Casting.h"
+#include "llvm/IR/User.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/IR/User.h"
#include "gtest/gtest.h"
#include <cstdlib>
@@ -18,7 +18,7 @@ namespace llvm {
// Used to test illegal cast. If a cast doesn't match any of the "real" ones,
// it will match this one.
struct IllegalCast;
-template <typename T> IllegalCast *cast(...) { return 0; }
+template <typename T> IllegalCast *cast(...) { return nullptr; }
// set up two example classes
// with conversion facility
@@ -77,16 +77,20 @@ using namespace llvm;
// Test the peculiar behavior of Use in simplify_type.
-int Check1[is_same<simplify_type<Use>::SimpleType, Value *>::value ? 1 : -1];
-int Check2[is_same<simplify_type<Use *>::SimpleType, Value *>::value ? 1 : -1];
+static_assert(std::is_same<simplify_type<Use>::SimpleType, Value *>::value,
+ "Use doesn't simplify correctly!");
+static_assert(std::is_same<simplify_type<Use *>::SimpleType, Value *>::value,
+ "Use doesn't simplify correctly!");
// Test that a regular class behaves as expected.
-int Check3[is_same<simplify_type<foo>::SimpleType, int>::value ? 1 : -1];
-int Check4[is_same<simplify_type<foo *>::SimpleType, foo *>::value ? 1 : -1];
+static_assert(std::is_same<simplify_type<foo>::SimpleType, int>::value,
+ "Unexpected simplify_type result!");
+static_assert(std::is_same<simplify_type<foo *>::SimpleType, foo *>::value,
+ "Unexpected simplify_type result!");
namespace {
-const foo *null_foo = NULL;
+const foo *null_foo = nullptr;
bar B;
extern bar &B1;
@@ -171,7 +175,7 @@ TEST(CastingTest, dyn_cast_or_null) {
const bar *B2 = &B;
} // anonymous namespace
-bar *llvm::fub() { return 0; }
+bar *llvm::fub() { return nullptr; }
namespace {
namespace inferred_upcasting {
@@ -199,7 +203,7 @@ TEST(CastingTest, UpcastIsInferred) {
Derived D;
EXPECT_TRUE(isa<Base>(D));
Base *BP = dyn_cast<Base>(&D);
- EXPECT_TRUE(BP != NULL);
+ EXPECT_TRUE(BP != nullptr);
}
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp
index c54e1b9570f8..e4a1b67c47ea 100644
--- a/unittests/Support/CommandLineTest.cpp
+++ b/unittests/Support/CommandLineTest.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/CommandLine.h"
#include "gtest/gtest.h"
#include <stdlib.h>
#include <string>
@@ -23,7 +23,7 @@ class TempEnvVar {
TempEnvVar(const char *name, const char *value)
: name(name) {
const char *old_value = getenv(name);
- EXPECT_EQ(NULL, old_value) << old_value;
+ EXPECT_EQ(nullptr, old_value) << old_value;
#if HAVE_SETENV
setenv(name, value, true);
#else
@@ -42,6 +42,33 @@ class TempEnvVar {
const char *const name;
};
+template <typename T>
+class StackOption : public cl::opt<T> {
+ typedef cl::opt<T> Base;
+public:
+ // One option...
+ template<class M0t>
+ explicit StackOption(const M0t &M0) : Base(M0) {}
+
+ // Two options...
+ template<class M0t, class M1t>
+ StackOption(const M0t &M0, const M1t &M1) : Base(M0, M1) {}
+
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ StackOption(const M0t &M0, const M1t &M1, const M2t &M2) : Base(M0, M1, M2) {}
+
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ StackOption(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Base(M0, M1, M2, M3) {}
+
+ ~StackOption() {
+ this->removeArgument();
+ }
+};
+
+
cl::OptionCategory TestCategory("Test Options", "Description");
cl::opt<int> TestOption("test-option", cl::desc("old description"));
TEST(CommandLineTest, ModifyExisitingOption) {
@@ -103,7 +130,7 @@ TEST(CommandLineTest, ParseEnvironment) {
// command line system will still hold a pointer to a deallocated cl::Option.
TEST(CommandLineTest, ParseEnvironmentToLocalVar) {
// Put cl::opt on stack to check for proper initialization of fields.
- cl::opt<std::string> EnvironmentTestOptionLocal("env-test-opt-local");
+ StackOption<std::string> EnvironmentTestOptionLocal("env-test-opt-local");
TempEnvVar TEV(test_env_var, "-env-test-opt-local=hello-local");
EXPECT_EQ("", EnvironmentTestOptionLocal);
cl::ParseEnvironmentOptions("CommandLineTest", test_env_var);
@@ -113,14 +140,14 @@ TEST(CommandLineTest, ParseEnvironmentToLocalVar) {
#endif // SKIP_ENVIRONMENT_TESTS
TEST(CommandLineTest, UseOptionCategory) {
- cl::opt<int> TestOption2("test-option", cl::cat(TestCategory));
+ StackOption<int> TestOption2("test-option", cl::cat(TestCategory));
ASSERT_EQ(&TestCategory,TestOption2.Category) << "Failed to assign Option "
"Category.";
}
class StrDupSaver : public cl::StringSaver {
- const char *SaveString(const char *Str) LLVM_OVERRIDE {
+ const char *SaveString(const char *Str) override {
return strdup(Str);
}
};
@@ -161,4 +188,47 @@ TEST(CommandLineTest, TokenizeWindowsCommandLine) {
array_lengthof(Output));
}
+TEST(CommandLineTest, AliasesWithArguments) {
+ static const size_t ARGC = 3;
+ const char *const Inputs[][ARGC] = {
+ { "-tool", "-actual=x", "-extra" },
+ { "-tool", "-actual", "x" },
+ { "-tool", "-alias=x", "-extra" },
+ { "-tool", "-alias", "x" }
+ };
+
+ for (size_t i = 0, e = array_lengthof(Inputs); i < e; ++i) {
+ StackOption<std::string> Actual("actual");
+ StackOption<bool> Extra("extra");
+ StackOption<std::string> Input(cl::Positional);
+
+ cl::alias Alias("alias", llvm::cl::aliasopt(Actual));
+
+ cl::ParseCommandLineOptions(ARGC, Inputs[i]);
+ EXPECT_EQ("x", Actual);
+ EXPECT_EQ(0, Input.getNumOccurrences());
+
+ Alias.removeArgument();
+ }
+}
+
+void testAliasRequired(int argc, const char *const *argv) {
+ StackOption<std::string> Option("option", cl::Required);
+ cl::alias Alias("o", llvm::cl::aliasopt(Option));
+
+ cl::ParseCommandLineOptions(argc, argv);
+ EXPECT_EQ("x", Option);
+ EXPECT_EQ(1, Option.getNumOccurrences());
+
+ Alias.removeArgument();
+}
+
+TEST(CommandLineTest, AliasRequired) {
+ const char *opts1[] = { "-tool", "-option=x" };
+ const char *opts2[] = { "-tool", "-o", "x" };
+ testAliasRequired(array_lengthof(opts1), opts1);
+ testAliasRequired(array_lengthof(opts2), opts2);
+}
+
+
} // anonymous namespace
diff --git a/unittests/Support/CompressionTest.cpp b/unittests/Support/CompressionTest.cpp
index c0a9adadb788..698ae3aa2fc0 100644
--- a/unittests/Support/CompressionTest.cpp
+++ b/unittests/Support/CompressionTest.cpp
@@ -12,10 +12,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Compression.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -25,20 +24,17 @@ namespace {
#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ
void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) {
- OwningPtr<MemoryBuffer> Compressed;
- OwningPtr<MemoryBuffer> Uncompressed;
+ SmallString<32> Compressed;
+ SmallString<32> Uncompressed;
EXPECT_EQ(zlib::StatusOK, zlib::compress(Input, Compressed, Level));
// Check that uncompressed buffer is the same as original.
- EXPECT_EQ(zlib::StatusOK, zlib::uncompress(Compressed->getBuffer(),
- Uncompressed, Input.size()));
- EXPECT_EQ(Input.size(), Uncompressed->getBufferSize());
- EXPECT_EQ(0,
- memcmp(Input.data(), Uncompressed->getBufferStart(), Input.size()));
+ EXPECT_EQ(zlib::StatusOK,
+ zlib::uncompress(Compressed, Uncompressed, Input.size()));
+ EXPECT_EQ(Input, Uncompressed);
if (Input.size() > 0) {
// Uncompression fails if expected length is too short.
EXPECT_EQ(zlib::StatusBufferTooShort,
- zlib::uncompress(Compressed->getBuffer(), Uncompressed,
- Input.size() - 1));
+ zlib::uncompress(Compressed, Uncompressed, Input.size() - 1));
}
}
diff --git a/unittests/Support/ConvertUTFTest.cpp b/unittests/Support/ConvertUTFTest.cpp
index 13ea75b1573b..16c9bebfde16 100644
--- a/unittests/Support/ConvertUTFTest.cpp
+++ b/unittests/Support/ConvertUTFTest.cpp
@@ -10,6 +10,8 @@
#include "llvm/Support/ConvertUTF.h"
#include "gtest/gtest.h"
#include <string>
+#include <vector>
+#include <utility>
using namespace llvm;
@@ -63,3 +65,1600 @@ TEST(ConvertUTFTest, HasUTF16BOM) {
HasBOM = hasUTF16ByteOrderMark(ArrayRef<char>("\xfe", 1));
EXPECT_FALSE(HasBOM);
}
+
+struct ConvertUTFResultContainer {
+ ConversionResult ErrorCode;
+ std::vector<unsigned> UnicodeScalars;
+
+ ConvertUTFResultContainer(ConversionResult ErrorCode)
+ : ErrorCode(ErrorCode) {}
+
+ ConvertUTFResultContainer
+ withScalars(unsigned US0 = 0x110000, unsigned US1 = 0x110000,
+ unsigned US2 = 0x110000, unsigned US3 = 0x110000,
+ unsigned US4 = 0x110000, unsigned US5 = 0x110000,
+ unsigned US6 = 0x110000, unsigned US7 = 0x110000) {
+ ConvertUTFResultContainer Result(*this);
+ if (US0 != 0x110000)
+ Result.UnicodeScalars.push_back(US0);
+ if (US1 != 0x110000)
+ Result.UnicodeScalars.push_back(US1);
+ if (US2 != 0x110000)
+ Result.UnicodeScalars.push_back(US2);
+ if (US3 != 0x110000)
+ Result.UnicodeScalars.push_back(US3);
+ if (US4 != 0x110000)
+ Result.UnicodeScalars.push_back(US4);
+ if (US5 != 0x110000)
+ Result.UnicodeScalars.push_back(US5);
+ if (US6 != 0x110000)
+ Result.UnicodeScalars.push_back(US6);
+ if (US7 != 0x110000)
+ Result.UnicodeScalars.push_back(US7);
+ return Result;
+ }
+};
+
+std::pair<ConversionResult, std::vector<unsigned>>
+ConvertUTF8ToUnicodeScalarsLenient(StringRef S) {
+ const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
+
+ const UTF8 *SourceNext = SourceStart;
+ std::vector<UTF32> Decoded(S.size(), 0);
+ UTF32 *TargetStart = Decoded.data();
+
+ auto ErrorCode =
+ ConvertUTF8toUTF32(&SourceNext, SourceStart + S.size(), &TargetStart,
+ Decoded.data() + Decoded.size(), lenientConversion);
+
+ Decoded.resize(TargetStart - Decoded.data());
+
+ return std::make_pair(ErrorCode, Decoded);
+}
+
+std::pair<ConversionResult, std::vector<unsigned>>
+ConvertUTF8ToUnicodeScalarsPartialLenient(StringRef S) {
+ const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
+
+ const UTF8 *SourceNext = SourceStart;
+ std::vector<UTF32> Decoded(S.size(), 0);
+ UTF32 *TargetStart = Decoded.data();
+
+ auto ErrorCode = ConvertUTF8toUTF32Partial(
+ &SourceNext, SourceStart + S.size(), &TargetStart,
+ Decoded.data() + Decoded.size(), lenientConversion);
+
+ Decoded.resize(TargetStart - Decoded.data());
+
+ return std::make_pair(ErrorCode, Decoded);
+}
+
+::testing::AssertionResult
+CheckConvertUTF8ToUnicodeScalars(ConvertUTFResultContainer Expected,
+ StringRef S, bool Partial = false) {
+ ConversionResult ErrorCode;
+ std::vector<unsigned> Decoded;
+ if (!Partial)
+ std::tie(ErrorCode, Decoded) = ConvertUTF8ToUnicodeScalarsLenient(S);
+ else
+
+ std::tie(ErrorCode, Decoded) = ConvertUTF8ToUnicodeScalarsPartialLenient(S);
+ if (Expected.ErrorCode != ErrorCode)
+ return ::testing::AssertionFailure() << "Expected error code "
+ << Expected.ErrorCode << ", actual "
+ << ErrorCode;
+
+ if (Expected.UnicodeScalars != Decoded)
+ return ::testing::AssertionFailure()
+ << "Expected lenient decoded result:\n"
+ << ::testing::PrintToString(Expected.UnicodeScalars) << "\n"
+ << "Actual result:\n" << ::testing::PrintToString(Decoded);
+
+ return ::testing::AssertionSuccess();
+}
+
+TEST(ConvertUTFTest, UTF8ToUTF32Lenient) {
+
+ //
+ // 1-byte sequences
+ //
+
+ // U+0041 LATIN CAPITAL LETTER A
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x0041), "\x41"));
+
+ //
+ // 2-byte sequences
+ //
+
+ // U+0283 LATIN SMALL LETTER ESH
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x0283),
+ "\xca\x83"));
+
+ // U+03BA GREEK SMALL LETTER KAPPA
+ // U+1F79 GREEK SMALL LETTER OMICRON WITH OXIA
+ // U+03C3 GREEK SMALL LETTER SIGMA
+ // U+03BC GREEK SMALL LETTER MU
+ // U+03B5 GREEK SMALL LETTER EPSILON
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK)
+ .withScalars(0x03ba, 0x1f79, 0x03c3, 0x03bc, 0x03b5),
+ "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5"));
+
+ //
+ // 3-byte sequences
+ //
+
+ // U+4F8B CJK UNIFIED IDEOGRAPH-4F8B
+ // U+6587 CJK UNIFIED IDEOGRAPH-6587
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x4f8b, 0x6587),
+ "\xe4\xbe\x8b\xe6\x96\x87"));
+
+ // U+D55C HANGUL SYLLABLE HAN
+ // U+AE00 HANGUL SYLLABLE GEUL
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xd55c, 0xae00),
+ "\xed\x95\x9c\xea\xb8\x80"));
+
+ // U+1112 HANGUL CHOSEONG HIEUH
+ // U+1161 HANGUL JUNGSEONG A
+ // U+11AB HANGUL JONGSEONG NIEUN
+ // U+1100 HANGUL CHOSEONG KIYEOK
+ // U+1173 HANGUL JUNGSEONG EU
+ // U+11AF HANGUL JONGSEONG RIEUL
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK)
+ .withScalars(0x1112, 0x1161, 0x11ab, 0x1100, 0x1173, 0x11af),
+ "\xe1\x84\x92\xe1\x85\xa1\xe1\x86\xab\xe1\x84\x80\xe1\x85\xb3"
+ "\xe1\x86\xaf"));
+
+ //
+ // 4-byte sequences
+ //
+
+ // U+E0100 VARIATION SELECTOR-17
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x000E0100),
+ "\xf3\xa0\x84\x80"));
+
+ //
+ // First possible sequence of a certain length
+ //
+
+ // U+0000 NULL
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x0000),
+ StringRef("\x00", 1)));
+
+ // U+0080 PADDING CHARACTER
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x0080),
+ "\xc2\x80"));
+
+ // U+0800 SAMARITAN LETTER ALAF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x0800),
+ "\xe0\xa0\x80"));
+
+ // U+10000 LINEAR B SYLLABLE B008 A
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x10000),
+ "\xf0\x90\x80\x80"));
+
+ // U+200000 (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf8\x88\x80\x80\x80"));
+
+ // U+4000000 (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x84\x80\x80\x80\x80"));
+
+ //
+ // Last possible sequence of a certain length
+ //
+
+ // U+007F DELETE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x007f), "\x7f"));
+
+ // U+07FF (unassigned)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x07ff),
+ "\xdf\xbf"));
+
+ // U+FFFF (noncharacter)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xffff),
+ "\xef\xbf\xbf"));
+
+ // U+1FFFFF (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf7\xbf\xbf\xbf"));
+
+ // U+3FFFFFF (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfb\xbf\xbf\xbf\xbf"));
+
+ // U+7FFFFFFF (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfd\xbf\xbf\xbf\xbf\xbf"));
+
+ //
+ // Other boundary conditions
+ //
+
+ // U+D7FF (unassigned)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xd7ff),
+ "\xed\x9f\xbf"));
+
+ // U+E000 (private use)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xe000),
+ "\xee\x80\x80"));
+
+ // U+FFFD REPLACEMENT CHARACTER
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfffd),
+ "\xef\xbf\xbd"));
+
+ // U+10FFFF (noncharacter)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x10ffff),
+ "\xf4\x8f\xbf\xbf"));
+
+ // U+110000 (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf4\x90\x80\x80"));
+
+ //
+ // Unexpected continuation bytes
+ //
+
+ // A sequence of unexpected continuation bytes that don't follow a first
+ // byte, every byte is a maximal subpart.
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\x80\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xbf\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\x80\xbf\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\x80\xbf\x80\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\x80\xbf\x82\xbf\xaa"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xaa\xb0\xbb\xbf\xaa\xa0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xaa\xb0\xbb\xbf\xaa\xa0\x8f"));
+
+ // All continuation bytes (0x80--0xbf).
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"));
+
+ //
+ // Lonely start bytes
+ //
+
+ // Start bytes of 2-byte sequences (0xc0--0xdf).
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020),
+ "\xc0\x20\xc1\x20\xc2\x20\xc3\x20\xc4\x20\xc5\x20\xc6\x20\xc7\x20"
+ "\xc8\x20\xc9\x20\xca\x20\xcb\x20\xcc\x20\xcd\x20\xce\x20\xcf\x20"
+ "\xd0\x20\xd1\x20\xd2\x20\xd3\x20\xd4\x20\xd5\x20\xd6\x20\xd7\x20"
+ "\xd8\x20\xd9\x20\xda\x20\xdb\x20\xdc\x20\xdd\x20\xde\x20\xdf\x20"));
+
+ // Start bytes of 3-byte sequences (0xe0--0xef).
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020),
+ "\xe0\x20\xe1\x20\xe2\x20\xe3\x20\xe4\x20\xe5\x20\xe6\x20\xe7\x20"
+ "\xe8\x20\xe9\x20\xea\x20\xeb\x20\xec\x20\xed\x20\xee\x20\xef\x20"));
+
+ // Start bytes of 4-byte sequences (0xf0--0xf7).
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+ 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020),
+ "\xf0\x20\xf1\x20\xf2\x20\xf3\x20\xf4\x20\xf5\x20\xf6\x20\xf7\x20"));
+
+ // Start bytes of 5-byte sequences (0xf8--0xfb).
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf8\xf9\xfa\xfb"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020),
+ "\xf8\x20\xf9\x20\xfa\x20\xfb\x20"));
+
+ // Start bytes of 6-byte sequences (0xfc--0xfd).
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfc\xfd"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020),
+ "\xfc\x20\xfd\x20"));
+
+ //
+ // Other bytes (0xc0--0xc1, 0xfe--0xff).
+ //
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xc0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xc1"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfe"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xff"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xc0\xc1\xfe\xff"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfe\xfe\xff\xff"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfe\x80\x80\x80\x80\x80"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xff\x80\x80\x80\x80\x80"));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+ 0xfffd, 0x0020, 0xfffd, 0x0020),
+ "\xc0\x20\xc1\x20\xfe\x20\xff\x20"));
+
+ //
+ // Sequences with one continuation byte missing
+ //
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xc2"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xdf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xe0\xa0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xe0\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xe1\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xec\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xed\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xed\x9f"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xee\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xef\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf0\x90\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf0\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf1\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf3\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf4\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf4\x8f\xbf"));
+
+ // Overlong sequences with one trailing byte missing.
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xc0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xc1"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xe0\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xe0\x9f"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf0\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf0\x8f\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf8\x80\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x80\x80\x80\x80"));
+
+ // Sequences that represent surrogates with one trailing byte missing.
+ // High surrogates
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xed\xa0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xed\xac"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xed\xaf"));
+ // Low surrogates
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xed\xb0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xed\xb4"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xed\xbf"));
+
+ // Ill-formed 4-byte sequences.
+ // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+1100xx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf4\x90\x80"));
+ // U+13FBxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf4\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf5\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf6\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf7\x80\x80"));
+ // U+1FFBxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf7\xbf\xbf"));
+
+ // Ill-formed 5-byte sequences.
+ // 111110uu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+2000xx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf8\x88\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf8\xbf\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf9\x80\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfa\x80\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfb\x80\x80\x80"));
+ // U+3FFFFxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfb\xbf\xbf\xbf"));
+
+ // Ill-formed 6-byte sequences.
+ // 1111110u 10uuuuuu 10uzzzzz 10zzzyyyy 10yyyyxx 10xxxxxx
+ // U+40000xx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x84\x80\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\xbf\xbf\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfd\x80\x80\x80\x80"));
+ // U+7FFFFFxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfd\xbf\xbf\xbf\xbf"));
+
+ //
+ // Sequences with two continuation bytes missing
+ //
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf0\x90"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf0\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf1\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf3\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf4\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+ "\xf4\x8f"));
+
+ // Overlong sequences with two trailing byte missing.
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xe0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf0\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf0\x8f"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf8\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x80\x80\x80"));
+
+ // Sequences that represent surrogates with two trailing bytes missing.
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xed"));
+
+ // Ill-formed 4-byte sequences.
+ // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+110yxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf4\x90"));
+ // U+13Fyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf4\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf5\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf6\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf7\x80"));
+ // U+1FFyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf7\xbf"));
+
+ // Ill-formed 5-byte sequences.
+ // 111110uu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+200yxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf8\x88\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf8\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xf9\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xfa\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xfb\x80\x80"));
+ // U+3FFFyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xfb\xbf\xbf"));
+
+ // Ill-formed 6-byte sequences.
+ // 1111110u 10uuuuuu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+4000yxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x84\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\xbf\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfd\x80\x80\x80"));
+ // U+7FFFFyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfd\xbf\xbf\xbf"));
+
+ //
+ // Sequences with three continuation bytes missing
+ //
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf1"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf2"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf3"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf4"));
+
+ // Broken overlong sequences.
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf0"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf8\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x80\x80"));
+
+ // Ill-formed 4-byte sequences.
+ // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+14yyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf5"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf6"));
+ // U+1Cyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf7"));
+
+ // Ill-formed 5-byte sequences.
+ // 111110uu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+20yyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf8\x88"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf8\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xf9\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfa\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfb\x80"));
+ // U+3FCyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfb\xbf"));
+
+ // Ill-formed 6-byte sequences.
+ // 1111110u 10uuuuuu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+400yyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x84\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xfc\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xfd\x80\x80"));
+ // U+7FFCyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xfd\xbf\xbf"));
+
+ //
+ // Sequences with four continuation bytes missing
+ //
+
+ // Ill-formed 5-byte sequences.
+ // 111110uu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+uzyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf8"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf9"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfa"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfb"));
+ // U+3zyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfb"));
+
+ // Broken overlong sequences.
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf8"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfc\x80"));
+
+ // Ill-formed 6-byte sequences.
+ // 1111110u 10uuuuuu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+uzzyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfc\x84"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfc\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfd\x80"));
+ // U+7Fzzyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xfd\xbf"));
+
+ //
+ // Sequences with five continuation bytes missing
+ //
+
+ // Ill-formed 6-byte sequences.
+ // 1111110u 10uuuuuu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+ // U+uzzyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfc"));
+ // U+uuzzyyxx (invalid)
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfd"));
+
+ //
+ // Consecutive sequences with trailing bytes missing
+ //
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, /**/ 0xfffd, 0xfffd, /**/ 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, /**/ 0xfffd, /**/ 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xc0" "\xe0\x80" "\xf0\x80\x80"
+ "\xf8\x80\x80\x80"
+ "\xfc\x80\x80\x80\x80"
+ "\xdf" "\xef\xbf" "\xf7\xbf\xbf"
+ "\xfb\xbf\xbf\xbf"
+ "\xfd\xbf\xbf\xbf\xbf"));
+
+ //
+ // Overlong UTF-8 sequences
+ //
+
+ // U+002F SOLIDUS
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x002f), "\x2f"));
+
+ // Overlong sequences of the above.
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xc0\xaf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xe0\x80\xaf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf0\x80\x80\xaf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf8\x80\x80\x80\xaf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x80\x80\x80\x80\xaf"));
+
+ // U+0000 NULL
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x0000),
+ StringRef("\x00", 1)));
+
+ // Overlong sequences of the above.
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xc0\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xe0\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf0\x80\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf8\x80\x80\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x80\x80\x80\x80\x80"));
+
+ // Other overlong sequences.
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xc0\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xc1\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+ "\xc1\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xe0\x9f\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xed\xa0\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xed\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf0\x8f\x80\x80"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf0\x8f\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xf8\x87\xbf\xbf\xbf"));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xfc\x83\xbf\xbf\xbf\xbf"));
+
+ //
+ // Isolated surrogates
+ //
+
+ // Unicode 6.3.0:
+ //
+ // D71. High-surrogate code point: A Unicode code point in the range
+ // U+D800 to U+DBFF.
+ //
+ // D73. Low-surrogate code point: A Unicode code point in the range
+ // U+DC00 to U+DFFF.
+
+ // Note: U+E0100 is <DB40 DD00> in UTF16.
+
+ // High surrogates
+
+ // U+D800
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xed\xa0\x80"));
+
+ // U+DB40
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xed\xac\xa0"));
+
+ // U+DBFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xed\xaf\xbf"));
+
+ // Low surrogates
+
+ // U+DC00
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xed\xb0\x80"));
+
+ // U+DD00
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xed\xb4\x80"));
+
+ // U+DFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd),
+ "\xed\xbf\xbf"));
+
+ // Surrogate pairs
+
+ // U+D800 U+DC00
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xa0\x80\xed\xb0\x80"));
+
+ // U+D800 U+DD00
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xa0\x80\xed\xb4\x80"));
+
+ // U+D800 U+DFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xa0\x80\xed\xbf\xbf"));
+
+ // U+DB40 U+DC00
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xac\xa0\xed\xb0\x80"));
+
+ // U+DB40 U+DD00
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xac\xa0\xed\xb4\x80"));
+
+ // U+DB40 U+DFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xac\xa0\xed\xbf\xbf"));
+
+ // U+DBFF U+DC00
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xaf\xbf\xed\xb0\x80"));
+
+ // U+DBFF U+DD00
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xaf\xbf\xed\xb4\x80"));
+
+ // U+DBFF U+DFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceIllegal)
+ .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+ "\xed\xaf\xbf\xed\xbf\xbf"));
+
+ //
+ // Noncharacters
+ //
+
+ // Unicode 6.3.0:
+ //
+ // D14. Noncharacter: A code point that is permanently reserved for
+ // internal use and that should never be interchanged. Noncharacters
+ // consist of the values U+nFFFE and U+nFFFF (where n is from 0 to 1016)
+ // and the values U+FDD0..U+FDEF.
+
+ // U+FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfffe),
+ "\xef\xbf\xbe"));
+
+ // U+FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xffff),
+ "\xef\xbf\xbf"));
+
+ // U+1FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x1fffe),
+ "\xf0\x9f\xbf\xbe"));
+
+ // U+1FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x1ffff),
+ "\xf0\x9f\xbf\xbf"));
+
+ // U+2FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x2fffe),
+ "\xf0\xaf\xbf\xbe"));
+
+ // U+2FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x2ffff),
+ "\xf0\xaf\xbf\xbf"));
+
+ // U+3FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x3fffe),
+ "\xf0\xbf\xbf\xbe"));
+
+ // U+3FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x3ffff),
+ "\xf0\xbf\xbf\xbf"));
+
+ // U+4FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x4fffe),
+ "\xf1\x8f\xbf\xbe"));
+
+ // U+4FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x4ffff),
+ "\xf1\x8f\xbf\xbf"));
+
+ // U+5FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x5fffe),
+ "\xf1\x9f\xbf\xbe"));
+
+ // U+5FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x5ffff),
+ "\xf1\x9f\xbf\xbf"));
+
+ // U+6FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x6fffe),
+ "\xf1\xaf\xbf\xbe"));
+
+ // U+6FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x6ffff),
+ "\xf1\xaf\xbf\xbf"));
+
+ // U+7FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x7fffe),
+ "\xf1\xbf\xbf\xbe"));
+
+ // U+7FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x7ffff),
+ "\xf1\xbf\xbf\xbf"));
+
+ // U+8FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x8fffe),
+ "\xf2\x8f\xbf\xbe"));
+
+ // U+8FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x8ffff),
+ "\xf2\x8f\xbf\xbf"));
+
+ // U+9FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x9fffe),
+ "\xf2\x9f\xbf\xbe"));
+
+ // U+9FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x9ffff),
+ "\xf2\x9f\xbf\xbf"));
+
+ // U+AFFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xafffe),
+ "\xf2\xaf\xbf\xbe"));
+
+ // U+AFFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xaffff),
+ "\xf2\xaf\xbf\xbf"));
+
+ // U+BFFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xbfffe),
+ "\xf2\xbf\xbf\xbe"));
+
+ // U+BFFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xbffff),
+ "\xf2\xbf\xbf\xbf"));
+
+ // U+CFFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xcfffe),
+ "\xf3\x8f\xbf\xbe"));
+
+ // U+CFFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xcfffF),
+ "\xf3\x8f\xbf\xbf"));
+
+ // U+DFFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xdfffe),
+ "\xf3\x9f\xbf\xbe"));
+
+ // U+DFFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xdffff),
+ "\xf3\x9f\xbf\xbf"));
+
+ // U+EFFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xefffe),
+ "\xf3\xaf\xbf\xbe"));
+
+ // U+EFFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xeffff),
+ "\xf3\xaf\xbf\xbf"));
+
+ // U+FFFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xffffe),
+ "\xf3\xbf\xbf\xbe"));
+
+ // U+FFFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfffff),
+ "\xf3\xbf\xbf\xbf"));
+
+ // U+10FFFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x10fffe),
+ "\xf4\x8f\xbf\xbe"));
+
+ // U+10FFFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x10ffff),
+ "\xf4\x8f\xbf\xbf"));
+
+ // U+FDD0
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd0),
+ "\xef\xb7\x90"));
+
+ // U+FDD1
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd1),
+ "\xef\xb7\x91"));
+
+ // U+FDD2
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd2),
+ "\xef\xb7\x92"));
+
+ // U+FDD3
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd3),
+ "\xef\xb7\x93"));
+
+ // U+FDD4
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd4),
+ "\xef\xb7\x94"));
+
+ // U+FDD5
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd5),
+ "\xef\xb7\x95"));
+
+ // U+FDD6
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd6),
+ "\xef\xb7\x96"));
+
+ // U+FDD7
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd7),
+ "\xef\xb7\x97"));
+
+ // U+FDD8
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd8),
+ "\xef\xb7\x98"));
+
+ // U+FDD9
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdd9),
+ "\xef\xb7\x99"));
+
+ // U+FDDA
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdda),
+ "\xef\xb7\x9a"));
+
+ // U+FDDB
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfddb),
+ "\xef\xb7\x9b"));
+
+ // U+FDDC
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfddc),
+ "\xef\xb7\x9c"));
+
+ // U+FDDD
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfddd),
+ "\xef\xb7\x9d"));
+
+ // U+FDDE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdde),
+ "\xef\xb7\x9e"));
+
+ // U+FDDF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfddf),
+ "\xef\xb7\x9f"));
+
+ // U+FDE0
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde0),
+ "\xef\xb7\xa0"));
+
+ // U+FDE1
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde1),
+ "\xef\xb7\xa1"));
+
+ // U+FDE2
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde2),
+ "\xef\xb7\xa2"));
+
+ // U+FDE3
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde3),
+ "\xef\xb7\xa3"));
+
+ // U+FDE4
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde4),
+ "\xef\xb7\xa4"));
+
+ // U+FDE5
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde5),
+ "\xef\xb7\xa5"));
+
+ // U+FDE6
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde6),
+ "\xef\xb7\xa6"));
+
+ // U+FDE7
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde7),
+ "\xef\xb7\xa7"));
+
+ // U+FDE8
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde8),
+ "\xef\xb7\xa8"));
+
+ // U+FDE9
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfde9),
+ "\xef\xb7\xa9"));
+
+ // U+FDEA
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdea),
+ "\xef\xb7\xaa"));
+
+ // U+FDEB
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdeb),
+ "\xef\xb7\xab"));
+
+ // U+FDEC
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdec),
+ "\xef\xb7\xac"));
+
+ // U+FDED
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfded),
+ "\xef\xb7\xad"));
+
+ // U+FDEE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdee),
+ "\xef\xb7\xae"));
+
+ // U+FDEF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdef),
+ "\xef\xb7\xaf"));
+
+ // U+FDF0
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf0),
+ "\xef\xb7\xb0"));
+
+ // U+FDF1
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf1),
+ "\xef\xb7\xb1"));
+
+ // U+FDF2
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf2),
+ "\xef\xb7\xb2"));
+
+ // U+FDF3
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf3),
+ "\xef\xb7\xb3"));
+
+ // U+FDF4
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf4),
+ "\xef\xb7\xb4"));
+
+ // U+FDF5
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf5),
+ "\xef\xb7\xb5"));
+
+ // U+FDF6
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf6),
+ "\xef\xb7\xb6"));
+
+ // U+FDF7
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf7),
+ "\xef\xb7\xb7"));
+
+ // U+FDF8
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf8),
+ "\xef\xb7\xb8"));
+
+ // U+FDF9
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdf9),
+ "\xef\xb7\xb9"));
+
+ // U+FDFA
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdfa),
+ "\xef\xb7\xba"));
+
+ // U+FDFB
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdfb),
+ "\xef\xb7\xbb"));
+
+ // U+FDFC
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdfc),
+ "\xef\xb7\xbc"));
+
+ // U+FDFD
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdfd),
+ "\xef\xb7\xbd"));
+
+ // U+FDFE
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdfe),
+ "\xef\xb7\xbe"));
+
+ // U+FDFF
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0xfdff),
+ "\xef\xb7\xbf"));
+}
+
+TEST(ConvertUTFTest, UTF8ToUTF32PartialLenient) {
+ // U+0041 LATIN CAPITAL LETTER A
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(conversionOK).withScalars(0x0041),
+ "\x41", true));
+
+ //
+ // Sequences with one continuation byte missing
+ //
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xc2", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xdf", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xe0\xa0", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xe0\xbf", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xe1\x80", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xec\xbf", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xed\x80", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xed\x9f", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xee\x80", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xef\xbf", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xf0\x90\x80", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xf0\xbf\xbf", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xf1\x80\x80", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xf3\xbf\xbf", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xf4\x80\x80", true));
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted),
+ "\xf4\x8f\xbf", true));
+
+ EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+ ConvertUTFResultContainer(sourceExhausted).withScalars(0x0041),
+ "\x41\xc2", true));
+}
+
diff --git a/unittests/Support/DataExtractorTest.cpp b/unittests/Support/DataExtractorTest.cpp
index ec8bd3d18c8a..81de983d2265 100644
--- a/unittests/Support/DataExtractorTest.cpp
+++ b/unittests/Support/DataExtractorTest.cpp
@@ -94,7 +94,7 @@ TEST(DataExtractorTest, Strings) {
EXPECT_EQ(stringData, DE.getCStr(&offset));
EXPECT_EQ(11U, offset);
- EXPECT_EQ(NULL, DE.getCStr(&offset));
+ EXPECT_EQ(nullptr, DE.getCStr(&offset));
EXPECT_EQ(11U, offset);
}
diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp
index feb6a086e194..d76e7d62421f 100644
--- a/unittests/Support/ErrorOrTest.cpp
+++ b/unittests/Support/ErrorOrTest.cpp
@@ -8,9 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/ErrorOr.h"
-
+#include "llvm/Support/Errc.h"
#include "gtest/gtest.h"
-
#include <memory>
using namespace llvm;
@@ -22,22 +21,25 @@ ErrorOr<int> t2() { return errc::invalid_argument; }
TEST(ErrorOr, SimpleValue) {
ErrorOr<int> a = t1();
- EXPECT_TRUE(a);
+ // FIXME: This is probably a bug in gtest. EXPECT_TRUE should expand to
+ // include the !! to make it friendly to explicit bool operators.
+ EXPECT_TRUE(!!a);
EXPECT_EQ(1, *a);
+ ErrorOr<int> b = a;
+ EXPECT_EQ(1, *b);
+
a = t2();
EXPECT_FALSE(a);
- EXPECT_EQ(errc::invalid_argument, a);
+ EXPECT_EQ(a.getError(), errc::invalid_argument);
#ifdef EXPECT_DEBUG_DEATH
EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists");
#endif
}
-#if LLVM_HAS_CXX11_STDLIB
ErrorOr<std::unique_ptr<int> > t3() {
return std::unique_ptr<int>(new int(3));
}
-#endif
TEST(ErrorOr, Types) {
int x;
@@ -45,22 +47,18 @@ TEST(ErrorOr, Types) {
*a = 42;
EXPECT_EQ(42, x);
-#if LLVM_HAS_CXX11_STDLIB
// Move only types.
EXPECT_EQ(3, **t3());
-#endif
}
struct B {};
struct D : B {};
TEST(ErrorOr, Covariant) {
- ErrorOr<B*> b(ErrorOr<D*>(0));
- b = ErrorOr<D*>(0);
+ ErrorOr<B*> b(ErrorOr<D*>(nullptr));
+ b = ErrorOr<D*>(nullptr);
-#if LLVM_HAS_CXX11_STDLIB
- ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(0));
- b1 = ErrorOr<std::unique_ptr<D> >(0);
-#endif
+ ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(nullptr));
+ b1 = ErrorOr<std::unique_ptr<D> >(nullptr);
}
} // end anon namespace
diff --git a/unittests/Support/FileOutputBufferTest.cpp b/unittests/Support/FileOutputBufferTest.cpp
index 5e873193f288..b086f1e118d2 100644
--- a/unittests/Support/FileOutputBufferTest.cpp
+++ b/unittests/Support/FileOutputBufferTest.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/FileOutputBuffer.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@@ -18,12 +17,13 @@
using namespace llvm;
using namespace llvm::sys;
-#define ASSERT_NO_ERROR(x) \
- if (error_code ASSERT_NO_ERROR_ec = x) { \
- errs() << #x ": did not return errc::success.\n" \
- << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
- << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
- } else {}
+#define ASSERT_NO_ERROR(x) \
+ if (std::error_code ASSERT_NO_ERROR_ec = x) { \
+ errs() << #x ": did not return errc::success.\n" \
+ << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
+ << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
+ } else { \
+ }
namespace {
TEST(FileOutputBuffer, Test) {
@@ -38,7 +38,7 @@ TEST(FileOutputBuffer, Test) {
SmallString<128> File1(TestDirectory);
File1.append("/file1");
{
- OwningPtr<FileOutputBuffer> Buffer;
+ std::unique_ptr<FileOutputBuffer> Buffer;
ASSERT_NO_ERROR(FileOutputBuffer::create(File1, 8192, Buffer));
// Start buffer with special header.
memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
@@ -47,36 +47,34 @@ TEST(FileOutputBuffer, Test) {
// Commit buffer.
ASSERT_NO_ERROR(Buffer->commit());
}
- // Verify file exists and starts with special header.
- bool MagicMatches = false;
- ASSERT_NO_ERROR(fs::has_magic(Twine(File1), Twine("AABBCCDDEEFFGGHHIIJJ"),
- MagicMatches));
- EXPECT_TRUE(MagicMatches);
+
// Verify file is correct size.
uint64_t File1Size;
ASSERT_NO_ERROR(fs::file_size(Twine(File1), File1Size));
ASSERT_EQ(File1Size, 8192ULL);
+ ASSERT_NO_ERROR(fs::remove(File1.str()));
// TEST 2: Verify abort case.
SmallString<128> File2(TestDirectory);
File2.append("/file2");
{
- OwningPtr<FileOutputBuffer> Buffer2;
+ std::unique_ptr<FileOutputBuffer> Buffer2;
ASSERT_NO_ERROR(FileOutputBuffer::create(File2, 8192, Buffer2));
// Fill buffer with special header.
memcpy(Buffer2->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
// Do *not* commit buffer.
}
- // Verify file does not exist (because buffer not commited).
+ // Verify file does not exist (because buffer not committed).
bool Exists = false;
ASSERT_NO_ERROR(fs::exists(Twine(File2), Exists));
EXPECT_FALSE(Exists);
+ ASSERT_NO_ERROR(fs::remove(File2.str()));
// TEST 3: Verify sizing down case.
SmallString<128> File3(TestDirectory);
File3.append("/file3");
{
- OwningPtr<FileOutputBuffer> Buffer;
+ std::unique_ptr<FileOutputBuffer> Buffer;
ASSERT_NO_ERROR(FileOutputBuffer::create(File3, 8192000, Buffer));
// Start buffer with special header.
memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
@@ -85,21 +83,18 @@ TEST(FileOutputBuffer, Test) {
// Commit buffer, but size down to smaller size
ASSERT_NO_ERROR(Buffer->commit(5000));
}
- // Verify file exists and starts with special header.
- bool MagicMatches3 = false;
- ASSERT_NO_ERROR(fs::has_magic(Twine(File3), Twine("AABBCCDDEEFFGGHHIIJJ"),
- MagicMatches3));
- EXPECT_TRUE(MagicMatches3);
+
// Verify file is correct size.
uint64_t File3Size;
ASSERT_NO_ERROR(fs::file_size(Twine(File3), File3Size));
ASSERT_EQ(File3Size, 5000ULL);
+ ASSERT_NO_ERROR(fs::remove(File3.str()));
// TEST 4: Verify file can be made executable.
SmallString<128> File4(TestDirectory);
File4.append("/file4");
{
- OwningPtr<FileOutputBuffer> Buffer;
+ std::unique_ptr<FileOutputBuffer> Buffer;
ASSERT_NO_ERROR(FileOutputBuffer::create(File4, 8192, Buffer,
FileOutputBuffer::F_executable));
// Start buffer with special header.
@@ -112,9 +107,9 @@ TEST(FileOutputBuffer, Test) {
ASSERT_NO_ERROR(fs::status(Twine(File4), Status));
bool IsExecutable = (Status.permissions() & fs::owner_exe);
EXPECT_TRUE(IsExecutable);
+ ASSERT_NO_ERROR(fs::remove(File4.str()));
// Clean up.
- uint32_t RemovedCount;
- ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), RemovedCount));
+ ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
}
} // anonymous namespace
diff --git a/unittests/Support/IteratorTest.cpp b/unittests/Support/IteratorTest.cpp
new file mode 100644
index 000000000000..83848328c0c6
--- /dev/null
+++ b/unittests/Support/IteratorTest.cpp
@@ -0,0 +1,101 @@
+//===- IteratorTest.cpp - Unit tests for iterator utilities ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(PointeeIteratorTest, Basic) {
+ int arr[4] = { 1, 2, 3, 4 };
+ SmallVector<int *, 4> V;
+ V.push_back(&arr[0]);
+ V.push_back(&arr[1]);
+ V.push_back(&arr[2]);
+ V.push_back(&arr[3]);
+
+ typedef pointee_iterator<SmallVectorImpl<int *>::const_iterator> test_iterator;
+
+ test_iterator Begin, End;
+ Begin = V.begin();
+ End = test_iterator(V.end());
+
+ test_iterator I = Begin;
+ for (int i = 0; i < 4; ++i) {
+ EXPECT_EQ(*V[i], *I);
+
+ EXPECT_EQ(I, Begin + i);
+ EXPECT_EQ(I, std::next(Begin, i));
+ test_iterator J = Begin;
+ J += i;
+ EXPECT_EQ(I, J);
+ EXPECT_EQ(*V[i], Begin[i]);
+
+ EXPECT_NE(I, End);
+ EXPECT_GT(End, I);
+ EXPECT_LT(I, End);
+ EXPECT_GE(I, Begin);
+ EXPECT_LE(Begin, I);
+
+ EXPECT_EQ(i, I - Begin);
+ EXPECT_EQ(i, std::distance(Begin, I));
+ EXPECT_EQ(Begin, I - i);
+
+ test_iterator K = I++;
+ EXPECT_EQ(K, std::prev(I));
+ }
+ EXPECT_EQ(End, I);
+}
+
+TEST(PointeeIteratorTest, SmartPointer) {
+ SmallVector<std::unique_ptr<int>, 4> V;
+ V.push_back(make_unique<int>(1));
+ V.push_back(make_unique<int>(2));
+ V.push_back(make_unique<int>(3));
+ V.push_back(make_unique<int>(4));
+
+ typedef pointee_iterator<
+ SmallVectorImpl<std::unique_ptr<int>>::const_iterator> test_iterator;
+
+ test_iterator Begin, End;
+ Begin = V.begin();
+ End = test_iterator(V.end());
+
+ test_iterator I = Begin;
+ for (int i = 0; i < 4; ++i) {
+ EXPECT_EQ(*V[i], *I);
+
+ EXPECT_EQ(I, Begin + i);
+ EXPECT_EQ(I, std::next(Begin, i));
+ test_iterator J = Begin;
+ J += i;
+ EXPECT_EQ(I, J);
+ EXPECT_EQ(*V[i], Begin[i]);
+
+ EXPECT_NE(I, End);
+ EXPECT_GT(End, I);
+ EXPECT_LT(I, End);
+ EXPECT_GE(I, Begin);
+ EXPECT_LE(Begin, I);
+
+ EXPECT_EQ(i, I - Begin);
+ EXPECT_EQ(i, std::distance(Begin, I));
+ EXPECT_EQ(Begin, I - i);
+
+ test_iterator K = I++;
+ EXPECT_EQ(K, std::prev(I));
+ }
+ EXPECT_EQ(End, I);
+}
+
+} // anonymous namespace
diff --git a/unittests/Support/LEB128Test.cpp b/unittests/Support/LEB128Test.cpp
new file mode 100644
index 000000000000..b1ca13ef2416
--- /dev/null
+++ b/unittests/Support/LEB128Test.cpp
@@ -0,0 +1,311 @@
+//===- llvm/unittest/Support/LEB128Test.cpp - LEB128 function tests -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+using namespace llvm;
+
+namespace {
+
+TEST(LEB128Test, EncodeSLEB128) {
+#define EXPECT_SLEB128_EQ(EXPECTED, VALUE) \
+ do { \
+ /* encodeSLEB128(uint64_t, raw_ostream &) */ \
+ std::string Expected(EXPECTED, sizeof(EXPECTED) - 1); \
+ std::string Actual; \
+ raw_string_ostream Stream(Actual); \
+ encodeSLEB128(VALUE, Stream); \
+ Stream.flush(); \
+ EXPECT_EQ(Expected, Actual); \
+ } while (0)
+
+ // Encode SLEB128
+ EXPECT_SLEB128_EQ("\x00", 0);
+ EXPECT_SLEB128_EQ("\x01", 1);
+ EXPECT_SLEB128_EQ("\x7f", -1);
+ EXPECT_SLEB128_EQ("\x3f", 63);
+ EXPECT_SLEB128_EQ("\x41", -63);
+ EXPECT_SLEB128_EQ("\x40", -64);
+ EXPECT_SLEB128_EQ("\xbf\x7f", -65);
+ EXPECT_SLEB128_EQ("\xc0\x00", 64);
+
+#undef EXPECT_SLEB128_EQ
+}
+
+TEST(LEB128Test, EncodeULEB128) {
+#define EXPECT_ULEB128_EQ(EXPECTED, VALUE, PAD) \
+ do { \
+ std::string Expected(EXPECTED, sizeof(EXPECTED) - 1); \
+ \
+ /* encodeULEB128(uint64_t, raw_ostream &, unsigned) */ \
+ std::string Actual1; \
+ raw_string_ostream Stream(Actual1); \
+ encodeULEB128(VALUE, Stream, PAD); \
+ Stream.flush(); \
+ EXPECT_EQ(Expected, Actual1); \
+ \
+ /* encodeULEB128(uint64_t, uint8_t *, unsigned) */ \
+ uint8_t Buffer[32]; \
+ unsigned Size = encodeULEB128(VALUE, Buffer, PAD); \
+ std::string Actual2(reinterpret_cast<const char *>(Buffer), Size); \
+ EXPECT_EQ(Expected, Actual2); \
+ } while (0)
+
+ // Encode ULEB128
+ EXPECT_ULEB128_EQ("\x00", 0, 0);
+ EXPECT_ULEB128_EQ("\x01", 1, 0);
+ EXPECT_ULEB128_EQ("\x3f", 63, 0);
+ EXPECT_ULEB128_EQ("\x40", 64, 0);
+ EXPECT_ULEB128_EQ("\x7f", 0x7f, 0);
+ EXPECT_ULEB128_EQ("\x80\x01", 0x80, 0);
+ EXPECT_ULEB128_EQ("\x81\x01", 0x81, 0);
+ EXPECT_ULEB128_EQ("\x90\x01", 0x90, 0);
+ EXPECT_ULEB128_EQ("\xff\x01", 0xff, 0);
+ EXPECT_ULEB128_EQ("\x80\x02", 0x100, 0);
+ EXPECT_ULEB128_EQ("\x81\x02", 0x101, 0);
+
+ // Encode ULEB128 with some extra padding bytes
+ EXPECT_ULEB128_EQ("\x80\x00", 0, 1);
+ EXPECT_ULEB128_EQ("\x80\x80\x00", 0, 2);
+ EXPECT_ULEB128_EQ("\xff\x00", 0x7f, 1);
+ EXPECT_ULEB128_EQ("\xff\x80\x00", 0x7f, 2);
+ EXPECT_ULEB128_EQ("\x80\x81\x00", 0x80, 1);
+ EXPECT_ULEB128_EQ("\x80\x81\x80\x00", 0x80, 2);
+
+#undef EXPECT_ULEB128_EQ
+}
+
+TEST(LEB128Test, DecodeULEB128) {
+#define EXPECT_DECODE_ULEB128_EQ(EXPECTED, VALUE) \
+ do { \
+ unsigned ActualSize = 0; \
+ uint64_t Actual = decodeULEB128(reinterpret_cast<const uint8_t *>(VALUE), \
+ &ActualSize); \
+ EXPECT_EQ(sizeof(VALUE) - 1, ActualSize); \
+ EXPECT_EQ(EXPECTED, Actual); \
+ } while (0)
+
+ // Decode ULEB128
+ EXPECT_DECODE_ULEB128_EQ(0u, "\x00");
+ EXPECT_DECODE_ULEB128_EQ(1u, "\x01");
+ EXPECT_DECODE_ULEB128_EQ(63u, "\x3f");
+ EXPECT_DECODE_ULEB128_EQ(64u, "\x40");
+ EXPECT_DECODE_ULEB128_EQ(0x7fu, "\x7f");
+ EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x01");
+ EXPECT_DECODE_ULEB128_EQ(0x81u, "\x81\x01");
+ EXPECT_DECODE_ULEB128_EQ(0x90u, "\x90\x01");
+ EXPECT_DECODE_ULEB128_EQ(0xffu, "\xff\x01");
+ EXPECT_DECODE_ULEB128_EQ(0x100u, "\x80\x02");
+ EXPECT_DECODE_ULEB128_EQ(0x101u, "\x81\x02");
+
+ // Decode ULEB128 with extra padding bytes
+ EXPECT_DECODE_ULEB128_EQ(0u, "\x80\x00");
+ EXPECT_DECODE_ULEB128_EQ(0u, "\x80\x80\x00");
+ EXPECT_DECODE_ULEB128_EQ(0x7fu, "\xff\x00");
+ EXPECT_DECODE_ULEB128_EQ(0x7fu, "\xff\x80\x00");
+ EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x81\x00");
+ EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x81\x80\x00");
+
+#undef EXPECT_DECODE_ULEB128_EQ
+}
+
+TEST(LEB128Test, SLEB128Size) {
+ // Positive Value Testing Plan:
+ // (1) 128 ^ n - 1 ........ need (n+1) bytes
+ // (2) 128 ^ n ............ need (n+1) bytes
+ // (3) 128 ^ n * 63 ....... need (n+1) bytes
+ // (4) 128 ^ n * 64 - 1 ... need (n+1) bytes
+ // (5) 128 ^ n * 64 ....... need (n+2) bytes
+
+ EXPECT_EQ(1u, getSLEB128Size(0x0LL));
+ EXPECT_EQ(1u, getSLEB128Size(0x1LL));
+ EXPECT_EQ(1u, getSLEB128Size(0x3fLL));
+ EXPECT_EQ(1u, getSLEB128Size(0x3fLL));
+ EXPECT_EQ(2u, getSLEB128Size(0x40LL));
+
+ EXPECT_EQ(2u, getSLEB128Size(0x7fLL));
+ EXPECT_EQ(2u, getSLEB128Size(0x80LL));
+ EXPECT_EQ(2u, getSLEB128Size(0x1f80LL));
+ EXPECT_EQ(2u, getSLEB128Size(0x1fffLL));
+ EXPECT_EQ(3u, getSLEB128Size(0x2000LL));
+
+ EXPECT_EQ(3u, getSLEB128Size(0x3fffLL));
+ EXPECT_EQ(3u, getSLEB128Size(0x4000LL));
+ EXPECT_EQ(3u, getSLEB128Size(0xfc000LL));
+ EXPECT_EQ(3u, getSLEB128Size(0xfffffLL));
+ EXPECT_EQ(4u, getSLEB128Size(0x100000LL));
+
+ EXPECT_EQ(4u, getSLEB128Size(0x1fffffLL));
+ EXPECT_EQ(4u, getSLEB128Size(0x200000LL));
+ EXPECT_EQ(4u, getSLEB128Size(0x7e00000LL));
+ EXPECT_EQ(4u, getSLEB128Size(0x7ffffffLL));
+ EXPECT_EQ(5u, getSLEB128Size(0x8000000LL));
+
+ EXPECT_EQ(5u, getSLEB128Size(0xfffffffLL));
+ EXPECT_EQ(5u, getSLEB128Size(0x10000000LL));
+ EXPECT_EQ(5u, getSLEB128Size(0x3f0000000LL));
+ EXPECT_EQ(5u, getSLEB128Size(0x3ffffffffLL));
+ EXPECT_EQ(6u, getSLEB128Size(0x400000000LL));
+
+ EXPECT_EQ(6u, getSLEB128Size(0x7ffffffffLL));
+ EXPECT_EQ(6u, getSLEB128Size(0x800000000LL));
+ EXPECT_EQ(6u, getSLEB128Size(0x1f800000000LL));
+ EXPECT_EQ(6u, getSLEB128Size(0x1ffffffffffLL));
+ EXPECT_EQ(7u, getSLEB128Size(0x20000000000LL));
+
+ EXPECT_EQ(7u, getSLEB128Size(0x3ffffffffffLL));
+ EXPECT_EQ(7u, getSLEB128Size(0x40000000000LL));
+ EXPECT_EQ(7u, getSLEB128Size(0xfc0000000000LL));
+ EXPECT_EQ(7u, getSLEB128Size(0xffffffffffffLL));
+ EXPECT_EQ(8u, getSLEB128Size(0x1000000000000LL));
+
+ EXPECT_EQ(8u, getSLEB128Size(0x1ffffffffffffLL));
+ EXPECT_EQ(8u, getSLEB128Size(0x2000000000000LL));
+ EXPECT_EQ(8u, getSLEB128Size(0x7e000000000000LL));
+ EXPECT_EQ(8u, getSLEB128Size(0x7fffffffffffffLL));
+ EXPECT_EQ(9u, getSLEB128Size(0x80000000000000LL));
+
+ EXPECT_EQ(9u, getSLEB128Size(0xffffffffffffffLL));
+ EXPECT_EQ(9u, getSLEB128Size(0x100000000000000LL));
+ EXPECT_EQ(9u, getSLEB128Size(0x3f00000000000000LL));
+ EXPECT_EQ(9u, getSLEB128Size(0x3fffffffffffffffLL));
+ EXPECT_EQ(10u, getSLEB128Size(0x4000000000000000LL));
+
+ EXPECT_EQ(10u, getSLEB128Size(0x7fffffffffffffffLL));
+ EXPECT_EQ(10u, getSLEB128Size(INT64_MAX));
+
+ // Negative Value Testing Plan:
+ // (1) - 128 ^ n - 1 ........ need (n+1) bytes
+ // (2) - 128 ^ n ............ need (n+1) bytes
+ // (3) - 128 ^ n * 63 ....... need (n+1) bytes
+ // (4) - 128 ^ n * 64 ....... need (n+1) bytes (different from positive one)
+ // (5) - 128 ^ n * 65 - 1 ... need (n+2) bytes (if n > 0)
+ // (6) - 128 ^ n * 65 ....... need (n+2) bytes
+
+ EXPECT_EQ(1u, getSLEB128Size(0x0LL));
+ EXPECT_EQ(1u, getSLEB128Size(-0x1LL));
+ EXPECT_EQ(1u, getSLEB128Size(-0x3fLL));
+ EXPECT_EQ(1u, getSLEB128Size(-0x40LL));
+ EXPECT_EQ(1u, getSLEB128Size(-0x40LL)); // special case
+ EXPECT_EQ(2u, getSLEB128Size(-0x41LL));
+
+ EXPECT_EQ(2u, getSLEB128Size(-0x7fLL));
+ EXPECT_EQ(2u, getSLEB128Size(-0x80LL));
+ EXPECT_EQ(2u, getSLEB128Size(-0x1f80LL));
+ EXPECT_EQ(2u, getSLEB128Size(-0x2000LL));
+ EXPECT_EQ(3u, getSLEB128Size(-0x207fLL));
+ EXPECT_EQ(3u, getSLEB128Size(-0x2080LL));
+
+ EXPECT_EQ(3u, getSLEB128Size(-0x3fffLL));
+ EXPECT_EQ(3u, getSLEB128Size(-0x4000LL));
+ EXPECT_EQ(3u, getSLEB128Size(-0xfc000LL));
+ EXPECT_EQ(3u, getSLEB128Size(-0x100000LL));
+ EXPECT_EQ(4u, getSLEB128Size(-0x103fffLL));
+ EXPECT_EQ(4u, getSLEB128Size(-0x104000LL));
+
+ EXPECT_EQ(4u, getSLEB128Size(-0x1fffffLL));
+ EXPECT_EQ(4u, getSLEB128Size(-0x200000LL));
+ EXPECT_EQ(4u, getSLEB128Size(-0x7e00000LL));
+ EXPECT_EQ(4u, getSLEB128Size(-0x8000000LL));
+ EXPECT_EQ(5u, getSLEB128Size(-0x81fffffLL));
+ EXPECT_EQ(5u, getSLEB128Size(-0x8200000LL));
+
+ EXPECT_EQ(5u, getSLEB128Size(-0xfffffffLL));
+ EXPECT_EQ(5u, getSLEB128Size(-0x10000000LL));
+ EXPECT_EQ(5u, getSLEB128Size(-0x3f0000000LL));
+ EXPECT_EQ(5u, getSLEB128Size(-0x400000000LL));
+ EXPECT_EQ(6u, getSLEB128Size(-0x40fffffffLL));
+ EXPECT_EQ(6u, getSLEB128Size(-0x410000000LL));
+
+ EXPECT_EQ(6u, getSLEB128Size(-0x7ffffffffLL));
+ EXPECT_EQ(6u, getSLEB128Size(-0x800000000LL));
+ EXPECT_EQ(6u, getSLEB128Size(-0x1f800000000LL));
+ EXPECT_EQ(6u, getSLEB128Size(-0x20000000000LL));
+ EXPECT_EQ(7u, getSLEB128Size(-0x207ffffffffLL));
+ EXPECT_EQ(7u, getSLEB128Size(-0x20800000000LL));
+
+ EXPECT_EQ(7u, getSLEB128Size(-0x3ffffffffffLL));
+ EXPECT_EQ(7u, getSLEB128Size(-0x40000000000LL));
+ EXPECT_EQ(7u, getSLEB128Size(-0xfc0000000000LL));
+ EXPECT_EQ(7u, getSLEB128Size(-0x1000000000000LL));
+ EXPECT_EQ(8u, getSLEB128Size(-0x103ffffffffffLL));
+ EXPECT_EQ(8u, getSLEB128Size(-0x1040000000000LL));
+
+ EXPECT_EQ(8u, getSLEB128Size(-0x1ffffffffffffLL));
+ EXPECT_EQ(8u, getSLEB128Size(-0x2000000000000LL));
+ EXPECT_EQ(8u, getSLEB128Size(-0x7e000000000000LL));
+ EXPECT_EQ(8u, getSLEB128Size(-0x80000000000000LL));
+ EXPECT_EQ(9u, getSLEB128Size(-0x81ffffffffffffLL));
+ EXPECT_EQ(9u, getSLEB128Size(-0x82000000000000LL));
+
+ EXPECT_EQ(9u, getSLEB128Size(-0xffffffffffffffLL));
+ EXPECT_EQ(9u, getSLEB128Size(-0x100000000000000LL));
+ EXPECT_EQ(9u, getSLEB128Size(-0x3f00000000000000LL));
+ EXPECT_EQ(9u, getSLEB128Size(-0x4000000000000000LL));
+ EXPECT_EQ(10u, getSLEB128Size(-0x40ffffffffffffffLL));
+ EXPECT_EQ(10u, getSLEB128Size(-0x4100000000000000LL));
+
+ EXPECT_EQ(10u, getSLEB128Size(-0x7fffffffffffffffLL));
+ EXPECT_EQ(10u, getSLEB128Size(-0x8000000000000000LL));
+ EXPECT_EQ(10u, getSLEB128Size(INT64_MIN));
+}
+
+TEST(LEB128Test, ULEB128Size) {
+ // Testing Plan:
+ // (1) 128 ^ n ............ need (n+1) bytes
+ // (2) 128 ^ n * 64 ....... need (n+1) bytes
+ // (3) 128 ^ (n+1) - 1 .... need (n+1) bytes
+
+ EXPECT_EQ(1u, getULEB128Size(0)); // special case
+
+ EXPECT_EQ(1u, getULEB128Size(0x1ULL));
+ EXPECT_EQ(1u, getULEB128Size(0x40ULL));
+ EXPECT_EQ(1u, getULEB128Size(0x7fULL));
+
+ EXPECT_EQ(2u, getULEB128Size(0x80ULL));
+ EXPECT_EQ(2u, getULEB128Size(0x2000ULL));
+ EXPECT_EQ(2u, getULEB128Size(0x3fffULL));
+
+ EXPECT_EQ(3u, getULEB128Size(0x4000ULL));
+ EXPECT_EQ(3u, getULEB128Size(0x100000ULL));
+ EXPECT_EQ(3u, getULEB128Size(0x1fffffULL));
+
+ EXPECT_EQ(4u, getULEB128Size(0x200000ULL));
+ EXPECT_EQ(4u, getULEB128Size(0x8000000ULL));
+ EXPECT_EQ(4u, getULEB128Size(0xfffffffULL));
+
+ EXPECT_EQ(5u, getULEB128Size(0x10000000ULL));
+ EXPECT_EQ(5u, getULEB128Size(0x400000000ULL));
+ EXPECT_EQ(5u, getULEB128Size(0x7ffffffffULL));
+
+ EXPECT_EQ(6u, getULEB128Size(0x800000000ULL));
+ EXPECT_EQ(6u, getULEB128Size(0x20000000000ULL));
+ EXPECT_EQ(6u, getULEB128Size(0x3ffffffffffULL));
+
+ EXPECT_EQ(7u, getULEB128Size(0x40000000000ULL));
+ EXPECT_EQ(7u, getULEB128Size(0x1000000000000ULL));
+ EXPECT_EQ(7u, getULEB128Size(0x1ffffffffffffULL));
+
+ EXPECT_EQ(8u, getULEB128Size(0x2000000000000ULL));
+ EXPECT_EQ(8u, getULEB128Size(0x80000000000000ULL));
+ EXPECT_EQ(8u, getULEB128Size(0xffffffffffffffULL));
+
+ EXPECT_EQ(9u, getULEB128Size(0x100000000000000ULL));
+ EXPECT_EQ(9u, getULEB128Size(0x4000000000000000ULL));
+ EXPECT_EQ(9u, getULEB128Size(0x7fffffffffffffffULL));
+
+ EXPECT_EQ(10u, getULEB128Size(0x8000000000000000ULL));
+
+ EXPECT_EQ(10u, getULEB128Size(UINT64_MAX));
+}
+
+} // anonymous namespace
diff --git a/unittests/Support/LineIteratorTest.cpp b/unittests/Support/LineIteratorTest.cpp
new file mode 100644
index 000000000000..18f3fa99bcde
--- /dev/null
+++ b/unittests/Support/LineIteratorTest.cpp
@@ -0,0 +1,115 @@
+//===- LineIterator.cpp - Unit tests --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::sys;
+
+namespace {
+
+TEST(LineIteratorTest, Basic) {
+ std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer("line 1\n"
+ "line 2\n"
+ "line 3"));
+
+ line_iterator I = line_iterator(*Buffer), E;
+
+ EXPECT_FALSE(I.is_at_eof());
+ EXPECT_NE(E, I);
+
+ EXPECT_EQ("line 1", *I);
+ EXPECT_EQ(1, I.line_number());
+ ++I;
+ EXPECT_EQ("line 2", *I);
+ EXPECT_EQ(2, I.line_number());
+ ++I;
+ EXPECT_EQ("line 3", *I);
+ EXPECT_EQ(3, I.line_number());
+ ++I;
+
+ EXPECT_TRUE(I.is_at_eof());
+ EXPECT_EQ(E, I);
+}
+
+TEST(LineIteratorTest, CommentSkipping) {
+ std::unique_ptr<MemoryBuffer> Buffer(
+ MemoryBuffer::getMemBuffer("line 1\n"
+ "line 2\n"
+ "# Comment 1\n"
+ "line 4\n"
+ "# Comment 2"));
+
+ line_iterator I = line_iterator(*Buffer, '#'), E;
+
+ EXPECT_FALSE(I.is_at_eof());
+ EXPECT_NE(E, I);
+
+ EXPECT_EQ("line 1", *I);
+ EXPECT_EQ(1, I.line_number());
+ ++I;
+ EXPECT_EQ("line 2", *I);
+ EXPECT_EQ(2, I.line_number());
+ ++I;
+ EXPECT_EQ("line 4", *I);
+ EXPECT_EQ(4, I.line_number());
+ ++I;
+
+ EXPECT_TRUE(I.is_at_eof());
+ EXPECT_EQ(E, I);
+}
+
+TEST(LineIteratorTest, BlankSkipping) {
+ std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer("\n\n\n"
+ "line 1\n"
+ "\n\n\n"
+ "line 2\n"
+ "\n\n\n"));
+
+ line_iterator I = line_iterator(*Buffer), E;
+
+ EXPECT_FALSE(I.is_at_eof());
+ EXPECT_NE(E, I);
+
+ EXPECT_EQ("line 1", *I);
+ EXPECT_EQ(4, I.line_number());
+ ++I;
+ EXPECT_EQ("line 2", *I);
+ EXPECT_EQ(8, I.line_number());
+ ++I;
+
+ EXPECT_TRUE(I.is_at_eof());
+ EXPECT_EQ(E, I);
+}
+
+TEST(LineIteratorTest, EmptyBuffers) {
+ std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(""));
+ EXPECT_TRUE(line_iterator(*Buffer).is_at_eof());
+ EXPECT_EQ(line_iterator(), line_iterator(*Buffer));
+
+ Buffer.reset(MemoryBuffer::getMemBuffer("\n\n\n"));
+ EXPECT_TRUE(line_iterator(*Buffer).is_at_eof());
+ EXPECT_EQ(line_iterator(), line_iterator(*Buffer));
+
+ Buffer.reset(MemoryBuffer::getMemBuffer("# foo\n"
+ "\n"
+ "# bar"));
+ EXPECT_TRUE(line_iterator(*Buffer, '#').is_at_eof());
+ EXPECT_EQ(line_iterator(), line_iterator(*Buffer, '#'));
+
+ Buffer.reset(MemoryBuffer::getMemBuffer("\n"
+ "# baz\n"
+ "\n"));
+ EXPECT_TRUE(line_iterator(*Buffer, '#').is_at_eof());
+ EXPECT_EQ(line_iterator(), line_iterator(*Buffer, '#'));
+}
+
+} // anonymous namespace
diff --git a/unittests/Support/LockFileManagerTest.cpp b/unittests/Support/LockFileManagerTest.cpp
index 5c73b9f5e235..885b7d605367 100644
--- a/unittests/Support/LockFileManagerTest.cpp
+++ b/unittests/Support/LockFileManagerTest.cpp
@@ -10,9 +10,7 @@
#include "llvm/Support/LockFileManager.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-
#include "gtest/gtest.h"
-
#include <memory>
using namespace llvm;
@@ -21,7 +19,7 @@ namespace {
TEST(LockFileManagerTest, Basic) {
SmallString<64> TmpDir;
- error_code EC;
+ std::error_code EC;
EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir);
ASSERT_FALSE(EC);
@@ -42,7 +40,88 @@ TEST(LockFileManagerTest, Basic) {
// Now that the lock is out of scope, the file should be gone.
EXPECT_FALSE(sys::fs::exists(StringRef(LockedFile)));
- sys::fs::remove_all(StringRef(TmpDir));
+ EC = sys::fs::remove(StringRef(TmpDir));
+ ASSERT_FALSE(EC);
+}
+
+TEST(LockFileManagerTest, LinkLockExists) {
+ SmallString<64> TmpDir;
+ std::error_code EC;
+ EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir);
+ ASSERT_FALSE(EC);
+
+ SmallString<64> LockedFile(TmpDir);
+ sys::path::append(LockedFile, "file");
+
+ SmallString<64> FileLocK(TmpDir);
+ sys::path::append(FileLocK, "file.lock");
+
+ SmallString<64> TmpFileLock(TmpDir);
+ sys::path::append(TmpFileLock, "file.lock-000");
+
+ int FD;
+ EC = sys::fs::openFileForWrite(StringRef(TmpFileLock), FD, sys::fs::F_None);
+ ASSERT_FALSE(EC);
+
+ int Ret = close(FD);
+ ASSERT_EQ(Ret, 0);
+
+ EC = sys::fs::create_link(TmpFileLock.str(), FileLocK.str());
+ ASSERT_FALSE(EC);
+
+ EC = sys::fs::remove(StringRef(TmpFileLock));
+ ASSERT_FALSE(EC);
+
+ {
+ // The lock file doesn't point to a real file, so we should successfully
+ // acquire it.
+ LockFileManager Locked(LockedFile);
+ EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState());
+ }
+
+ // Now that the lock is out of scope, the file should be gone.
+ EXPECT_FALSE(sys::fs::exists(StringRef(LockedFile)));
+
+ EC = sys::fs::remove(StringRef(TmpDir));
+ ASSERT_FALSE(EC);
+}
+
+
+TEST(LockFileManagerTest, RelativePath) {
+ SmallString<64> TmpDir;
+ std::error_code EC;
+ EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir);
+ ASSERT_FALSE(EC);
+
+ char PathBuf[1024];
+ const char *OrigPath = getcwd(PathBuf, 1024);
+ chdir(TmpDir.c_str());
+
+ sys::fs::create_directory("inner");
+ SmallString<64> LockedFile("inner");
+ sys::path::append(LockedFile, "file");
+
+ SmallString<64> FileLock(LockedFile);
+ FileLock += ".lock";
+
+ {
+ // The lock file should not exist, so we should successfully acquire it.
+ LockFileManager Locked(LockedFile);
+ EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState());
+ EXPECT_TRUE(sys::fs::exists(FileLock.str()));
+ }
+
+ // Now that the lock is out of scope, the file should be gone.
+ EXPECT_FALSE(sys::fs::exists(LockedFile.str()));
+ EXPECT_FALSE(sys::fs::exists(FileLock.str()));
+
+ EC = sys::fs::remove("inner");
+ ASSERT_FALSE(EC);
+
+ chdir(OrigPath);
+
+ EC = sys::fs::remove(StringRef(TmpDir));
+ ASSERT_FALSE(EC);
}
} // end anonymous namespace
diff --git a/unittests/Support/ManagedStatic.cpp b/unittests/Support/ManagedStatic.cpp
index 1497f4e34082..153884ba4298 100644
--- a/unittests/Support/ManagedStatic.cpp
+++ b/unittests/Support/ManagedStatic.cpp
@@ -25,7 +25,7 @@ namespace test1 {
llvm::ManagedStatic<int> ms;
void *helper(void*) {
*ms;
- return NULL;
+ return nullptr;
}
// Valgrind's leak checker complains glibc's stack allocation.
@@ -47,15 +47,13 @@ TEST(Initialize, MultipleThreads) {
void *p1 = test1::allocate_stack(a1);
void *p2 = test1::allocate_stack(a2);
- llvm_start_multithreaded();
pthread_t t1, t2;
- pthread_create(&t1, &a1, test1::helper, NULL);
- pthread_create(&t2, &a2, test1::helper, NULL);
- pthread_join(t1, NULL);
- pthread_join(t2, NULL);
+ pthread_create(&t1, &a1, test1::helper, nullptr);
+ pthread_create(&t2, &a2, test1::helper, nullptr);
+ pthread_join(t1, nullptr);
+ pthread_join(t2, nullptr);
free(p1);
free(p2);
- llvm_stop_multithreaded();
}
#endif
diff --git a/unittests/Support/MemoryBufferTest.cpp b/unittests/Support/MemoryBufferTest.cpp
index 2b8806c394f3..93bf301267ea 100644
--- a/unittests/Support/MemoryBufferTest.cpp
+++ b/unittests/Support/MemoryBufferTest.cpp
@@ -14,7 +14,6 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/OwningPtr.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -36,7 +35,7 @@ protected:
/// anew before using MemoryBuffer.
void testGetOpenFileSlice(bool Reopen);
- typedef OwningPtr<MemoryBuffer> OwningBuffer;
+ typedef std::unique_ptr<MemoryBuffer> OwningBuffer;
std::string data;
};
@@ -44,15 +43,15 @@ protected:
TEST_F(MemoryBufferTest, get) {
// Default name and null-terminator flag
OwningBuffer MB1(MemoryBuffer::getMemBuffer(data));
- EXPECT_TRUE(0 != MB1.get());
+ EXPECT_TRUE(nullptr != MB1.get());
// RequiresNullTerminator = false
OwningBuffer MB2(MemoryBuffer::getMemBuffer(data, "one", false));
- EXPECT_TRUE(0 != MB2.get());
+ EXPECT_TRUE(nullptr != MB2.get());
// RequiresNullTerminator = true
OwningBuffer MB3(MemoryBuffer::getMemBuffer(data, "two", true));
- EXPECT_TRUE(0 != MB3.get());
+ EXPECT_TRUE(nullptr != MB3.get());
// verify all 3 buffers point to the same address
EXPECT_EQ(MB1->getBufferStart(), MB2->getBufferStart());
@@ -78,11 +77,11 @@ TEST_F(MemoryBufferTest, NullTerminator4K) {
}
OF.close();
- OwningPtr<MemoryBuffer> MB;
- error_code EC = MemoryBuffer::getFile(TestPath.c_str(), MB);
+ ErrorOr<OwningBuffer> MB = MemoryBuffer::getFile(TestPath.c_str());
+ std::error_code EC = MB.getError();
ASSERT_FALSE(EC);
- const char *BufData = MB->getBufferStart();
+ const char *BufData = MB.get()->getBufferStart();
EXPECT_EQ('f', BufData[4095]);
EXPECT_EQ('\0', BufData[4096]);
}
@@ -90,11 +89,11 @@ TEST_F(MemoryBufferTest, NullTerminator4K) {
TEST_F(MemoryBufferTest, copy) {
// copy with no name
OwningBuffer MBC1(MemoryBuffer::getMemBufferCopy(data));
- EXPECT_TRUE(0 != MBC1.get());
+ EXPECT_TRUE(nullptr != MBC1.get());
// copy with a name
OwningBuffer MBC2(MemoryBuffer::getMemBufferCopy(data, "copy"));
- EXPECT_TRUE(0 != MBC2.get());
+ EXPECT_TRUE(nullptr != MBC2.get());
// verify the two copies do not point to the same place
EXPECT_NE(MBC1->getBufferStart(), MBC2->getBufferStart());
@@ -103,25 +102,25 @@ TEST_F(MemoryBufferTest, copy) {
TEST_F(MemoryBufferTest, make_new) {
// 0-sized buffer
OwningBuffer Zero(MemoryBuffer::getNewUninitMemBuffer(0));
- EXPECT_TRUE(0 != Zero.get());
+ EXPECT_TRUE(nullptr != Zero.get());
// uninitialized buffer with no name
OwningBuffer One(MemoryBuffer::getNewUninitMemBuffer(321));
- EXPECT_TRUE(0 != One.get());
+ EXPECT_TRUE(nullptr != One.get());
// uninitialized buffer with name
OwningBuffer Two(MemoryBuffer::getNewUninitMemBuffer(123, "bla"));
- EXPECT_TRUE(0 != Two.get());
+ EXPECT_TRUE(nullptr != Two.get());
// 0-initialized buffer with no name
OwningBuffer Three(MemoryBuffer::getNewMemBuffer(321, data));
- EXPECT_TRUE(0 != Three.get());
+ EXPECT_TRUE(nullptr != Three.get());
for (size_t i = 0; i < 321; ++i)
EXPECT_EQ(0, Three->getBufferStart()[0]);
// 0-initialized buffer with name
OwningBuffer Four(MemoryBuffer::getNewMemBuffer(123, "zeros"));
- EXPECT_TRUE(0 != Four.get());
+ EXPECT_TRUE(nullptr != Four.get());
for (size_t i = 0; i < 123; ++i)
EXPECT_EQ(0, Four->getBufferStart()[0]);
}
@@ -147,14 +146,16 @@ void MemoryBufferTest::testGetOpenFileSlice(bool Reopen) {
EXPECT_FALSE(sys::fs::openFileForRead(TestPath.c_str(), TestFD));
}
- OwningBuffer Buf;
- error_code EC = MemoryBuffer::getOpenFileSlice(TestFD, TestPath.c_str(), Buf,
- 40000, // Size
- 80000 // Offset
- );
+ ErrorOr<OwningBuffer> Buf =
+ MemoryBuffer::getOpenFileSlice(TestFD, TestPath.c_str(),
+ 40000, // Size
+ 80000 // Offset
+ );
+
+ std::error_code EC = Buf.getError();
EXPECT_FALSE(EC);
- StringRef BufData = Buf->getBuffer();
+ StringRef BufData = Buf.get()->getBuffer();
EXPECT_EQ(BufData.size(), 40000U);
EXPECT_EQ(BufData[0], '0');
EXPECT_EQ(BufData[9], '9');
diff --git a/unittests/Support/MemoryTest.cpp b/unittests/Support/MemoryTest.cpp
index fae67a8dd256..8ad90e045de9 100644
--- a/unittests/Support/MemoryTest.cpp
+++ b/unittests/Support/MemoryTest.cpp
@@ -57,30 +57,30 @@ protected:
};
TEST_P(MappedMemoryTest, AllocAndRelease) {
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ std::error_code EC;
+ MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
+ EXPECT_EQ(std::error_code(), EC);
- EXPECT_NE((void*)0, M1.base());
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(sizeof(int), M1.size());
EXPECT_FALSE(Memory::releaseMappedMemory(M1));
}
TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(64, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(32, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
+ std::error_code EC;
+ MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
+ EXPECT_EQ(std::error_code(), EC);
+ MemoryBlock M2 = Memory::allocateMappedMemory(64, nullptr, Flags, EC);
+ EXPECT_EQ(std::error_code(), EC);
+ MemoryBlock M3 = Memory::allocateMappedMemory(32, nullptr, Flags, EC);
+ EXPECT_EQ(std::error_code(), EC);
+
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
+ EXPECT_NE((void*)nullptr, M2.base());
EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
+ EXPECT_NE((void*)nullptr, M3.base());
EXPECT_LE(32U, M3.size());
EXPECT_FALSE(doesOverlap(M1, M2));
@@ -89,9 +89,9 @@ TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
EXPECT_FALSE(Memory::releaseMappedMemory(M1));
EXPECT_FALSE(Memory::releaseMappedMemory(M3));
- MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- EXPECT_NE((void*)0, M4.base());
+ MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
+ EXPECT_EQ(std::error_code(), EC);
+ EXPECT_NE((void*)nullptr, M4.base());
EXPECT_LE(16U, M4.size());
EXPECT_FALSE(Memory::releaseMappedMemory(M4));
EXPECT_FALSE(Memory::releaseMappedMemory(M2));
@@ -103,11 +103,11 @@ TEST_P(MappedMemoryTest, BasicWrite) {
!((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
return;
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ std::error_code EC;
+ MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
+ EXPECT_EQ(std::error_code(), EC);
- EXPECT_NE((void*)0, M1.base());
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(sizeof(int), M1.size());
int *a = (int*)M1.base();
@@ -122,23 +122,26 @@ TEST_P(MappedMemoryTest, MultipleWrite) {
if (Flags &&
!((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
return;
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ std::error_code EC;
+ MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
+ EC);
+ EXPECT_EQ(std::error_code(), EC);
+ MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
+ EC);
+ EXPECT_EQ(std::error_code(), EC);
+ MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
+ EC);
+ EXPECT_EQ(std::error_code(), EC);
EXPECT_FALSE(doesOverlap(M1, M2));
EXPECT_FALSE(doesOverlap(M2, M3));
EXPECT_FALSE(doesOverlap(M1, M3));
- EXPECT_NE((void*)0, M1.base());
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(1U * sizeof(int), M1.size());
- EXPECT_NE((void*)0, M2.base());
+ EXPECT_NE((void*)nullptr, M2.base());
EXPECT_LE(8U * sizeof(int), M2.size());
- EXPECT_NE((void*)0, M3.base());
+ EXPECT_NE((void*)nullptr, M3.base());
EXPECT_LE(4U * sizeof(int), M3.size());
int *x = (int*)M1.base();
@@ -159,9 +162,10 @@ TEST_P(MappedMemoryTest, MultipleWrite) {
EXPECT_FALSE(Memory::releaseMappedMemory(M1));
EXPECT_FALSE(Memory::releaseMappedMemory(M3));
- MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- EXPECT_NE((void*)0, M4.base());
+ MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), nullptr,
+ Flags, EC);
+ EXPECT_EQ(std::error_code(), EC);
+ EXPECT_NE((void*)nullptr, M4.base());
EXPECT_LE(64U * sizeof(int), M4.size());
x = (int*)M4.base();
*x = 4;
@@ -176,19 +180,22 @@ TEST_P(MappedMemoryTest, MultipleWrite) {
}
TEST_P(MappedMemoryTest, EnabledWrite) {
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
+ std::error_code EC;
+ MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
+ EC);
+ EXPECT_EQ(std::error_code(), EC);
+ MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
+ EC);
+ EXPECT_EQ(std::error_code(), EC);
+ MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
+ EC);
+ EXPECT_EQ(std::error_code(), EC);
+
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(2U * sizeof(int), M1.size());
- EXPECT_NE((void*)0, M2.base());
+ EXPECT_NE((void*)nullptr, M2.base());
EXPECT_LE(8U * sizeof(int), M2.size());
- EXPECT_NE((void*)0, M3.base());
+ EXPECT_NE((void*)nullptr, M3.base());
EXPECT_LE(4U * sizeof(int), M3.size());
EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
@@ -216,11 +223,12 @@ TEST_P(MappedMemoryTest, EnabledWrite) {
EXPECT_FALSE(Memory::releaseMappedMemory(M3));
EXPECT_EQ(6, y[6]);
- MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- EXPECT_NE((void*)0, M4.base());
+ MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
+ EXPECT_EQ(std::error_code(), EC);
+ EXPECT_NE((void*)nullptr, M4.base());
EXPECT_LE(16U, M4.size());
- EXPECT_EQ(error_code::success(), Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
+ EXPECT_EQ(std::error_code(),
+ Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
x = (int*)M4.base();
*x = 4;
EXPECT_EQ(4, *x);
@@ -229,19 +237,19 @@ TEST_P(MappedMemoryTest, EnabledWrite) {
}
TEST_P(MappedMemoryTest, SuccessiveNear) {
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ std::error_code EC;
+ MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
+ EXPECT_EQ(std::error_code(), EC);
MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
- EXPECT_NE((void*)0, M1.base());
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
+ EXPECT_NE((void*)nullptr, M2.base());
EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
+ EXPECT_NE((void*)nullptr, M3.base());
EXPECT_LE(32U, M3.size());
EXPECT_FALSE(doesOverlap(M1, M2));
@@ -254,20 +262,20 @@ TEST_P(MappedMemoryTest, SuccessiveNear) {
}
TEST_P(MappedMemoryTest, DuplicateNear) {
- error_code EC;
+ std::error_code EC;
MemoryBlock Near((void*)(3*PageSize), 16);
MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
- EXPECT_NE((void*)0, M1.base());
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
+ EXPECT_NE((void*)nullptr, M2.base());
EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
+ EXPECT_NE((void*)nullptr, M3.base());
EXPECT_LE(32U, M3.size());
EXPECT_FALSE(Memory::releaseMappedMemory(M1));
@@ -276,20 +284,20 @@ TEST_P(MappedMemoryTest, DuplicateNear) {
}
TEST_P(MappedMemoryTest, ZeroNear) {
- error_code EC;
- MemoryBlock Near(0, 0);
+ std::error_code EC;
+ MemoryBlock Near(nullptr, 0);
MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
- EXPECT_NE((void*)0, M1.base());
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
+ EXPECT_NE((void*)nullptr, M2.base());
EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
+ EXPECT_NE((void*)nullptr, M3.base());
EXPECT_LE(32U, M3.size());
EXPECT_FALSE(doesOverlap(M1, M2));
@@ -302,20 +310,20 @@ TEST_P(MappedMemoryTest, ZeroNear) {
}
TEST_P(MappedMemoryTest, ZeroSizeNear) {
- error_code EC;
+ std::error_code EC;
MemoryBlock Near((void*)(4*PageSize), 0);
MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
- EXPECT_NE((void*)0, M1.base());
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
+ EXPECT_NE((void*)nullptr, M2.base());
EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
+ EXPECT_NE((void*)nullptr, M3.base());
EXPECT_LE(32U, M3.size());
EXPECT_FALSE(doesOverlap(M1, M2));
@@ -328,12 +336,12 @@ TEST_P(MappedMemoryTest, ZeroSizeNear) {
}
TEST_P(MappedMemoryTest, UnalignedNear) {
- error_code EC;
+ std::error_code EC;
MemoryBlock Near((void*)(2*PageSize+5), 0);
MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
+ EXPECT_EQ(std::error_code(), EC);
- EXPECT_NE((void*)0, M1.base());
+ EXPECT_NE((void*)nullptr, M1.base());
EXPECT_LE(sizeof(int), M1.size());
EXPECT_FALSE(Memory::releaseMappedMemory(M1));
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index 031624162d0f..db85347e9212 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -8,24 +8,30 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Path.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
+#ifdef LLVM_ON_WIN32
+#include <winerror.h>
+#endif
+
using namespace llvm;
using namespace llvm::sys;
-#define ASSERT_NO_ERROR(x) \
- if (error_code ASSERT_NO_ERROR_ec = x) { \
- SmallString<128> MessageStorage; \
- raw_svector_ostream Message(MessageStorage); \
- Message << #x ": did not return errc::success.\n" \
- << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
- << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
- GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
- } else {}
+#define ASSERT_NO_ERROR(x) \
+ if (std::error_code ASSERT_NO_ERROR_ec = x) { \
+ SmallString<128> MessageStorage; \
+ raw_svector_ostream Message(MessageStorage); \
+ Message << #x ": did not return errc::success.\n" \
+ << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
+ << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
+ GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
+ } else { \
+ }
namespace {
@@ -85,6 +91,7 @@ TEST(Support, Path) {
paths.push_back("c:\\foo/");
paths.push_back("c:/foo\\bar");
+ SmallVector<StringRef, 5> ComponentStack;
for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
e = paths.end();
i != e;
@@ -94,18 +101,17 @@ TEST(Support, Path) {
ci != ce;
++ci) {
ASSERT_FALSE(ci->empty());
+ ComponentStack.push_back(*ci);
}
-#if 0 // Valgrind is whining about this.
- outs() << " Reverse Iteration: [";
for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
ce = sys::path::rend(*i);
ci != ce;
++ci) {
- outs() << *ci << ',';
+ ASSERT_TRUE(*ci == ComponentStack.back());
+ ComponentStack.pop_back();
}
- outs() << "]\n";
-#endif
+ ASSERT_TRUE(ComponentStack.empty());
path::has_root_path(*i);
path::root_path(*i);
@@ -210,6 +216,48 @@ TEST(Support, AbsolutePathIteratorWin32) {
}
#endif // LLVM_ON_WIN32
+TEST(Support, AbsolutePathIteratorEnd) {
+ // Trailing slashes are converted to '.' unless they are part of the root path.
+ SmallVector<StringRef, 4> Paths;
+ Paths.push_back("/foo/");
+ Paths.push_back("/foo//");
+ Paths.push_back("//net//");
+#ifdef LLVM_ON_WIN32
+ Paths.push_back("c:\\\\");
+#endif
+
+ for (StringRef Path : Paths) {
+ StringRef LastComponent = *--path::end(Path);
+ EXPECT_EQ(".", LastComponent);
+ }
+
+ SmallVector<StringRef, 3> RootPaths;
+ RootPaths.push_back("/");
+ RootPaths.push_back("//net/");
+#ifdef LLVM_ON_WIN32
+ RootPaths.push_back("c:\\");
+#endif
+
+ for (StringRef Path : RootPaths) {
+ StringRef LastComponent = *--path::end(Path);
+ EXPECT_EQ(1u, LastComponent.size());
+ EXPECT_TRUE(path::is_separator(LastComponent[0]));
+ }
+}
+
+TEST(Support, HomeDirectory) {
+#ifdef LLVM_ON_UNIX
+ // This test only makes sense on Unix if $HOME is set.
+ if (::getenv("HOME")) {
+#endif
+ SmallString<128> HomeDir;
+ EXPECT_TRUE(path::home_directory(HomeDir));
+ EXPECT_FALSE(HomeDir.empty());
+#ifdef LLVM_ON_UNIX
+ }
+#endif
+}
+
class FileSystemTest : public testing::Test {
protected:
/// Unique temporary directory in which all created filesystem entities must
@@ -225,8 +273,7 @@ protected:
}
virtual void TearDown() {
- uint32_t removed;
- ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), removed));
+ ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
}
};
@@ -258,7 +305,7 @@ TEST_F(FileSystemTest, Unique) {
// Two paths representing the same file on disk should still provide the
// same unique id. We can test this by making a hard link.
- ASSERT_NO_ERROR(fs::create_hard_link(Twine(TempPath), Twine(TempPath2)));
+ ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
fs::UniqueID D2;
ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D2));
ASSERT_EQ(D2, F1);
@@ -306,10 +353,12 @@ TEST_F(FileSystemTest, TempFiles) {
::close(FD2);
// Remove Temp2.
- ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists));
- EXPECT_TRUE(TempFileExists);
+ ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
+ ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
+ ASSERT_EQ(fs::remove(Twine(TempPath2), false),
+ errc::no_such_file_or_directory);
- error_code EC = fs::status(TempPath2.c_str(), B);
+ std::error_code EC = fs::status(TempPath2.c_str(), B);
EXPECT_EQ(EC, errc::no_such_file_or_directory);
EXPECT_EQ(B.type(), fs::file_type::file_not_found);
@@ -322,7 +371,7 @@ TEST_F(FileSystemTest, TempFiles) {
ASSERT_FALSE(TempPath3.endswith("."));
// Create a hard link to Temp1.
- ASSERT_NO_ERROR(fs::create_hard_link(Twine(TempPath), Twine(TempPath2)));
+ ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
bool equal;
ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
EXPECT_TRUE(equal);
@@ -332,12 +381,10 @@ TEST_F(FileSystemTest, TempFiles) {
// Remove Temp1.
::close(FileDescriptor);
- ASSERT_NO_ERROR(fs::remove(Twine(TempPath), TempFileExists));
- EXPECT_TRUE(TempFileExists);
+ ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
// Remove the hard link.
- ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists));
- EXPECT_TRUE(TempFileExists);
+ ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
// Make sure Temp1 doesn't exist.
ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists));
@@ -352,27 +399,34 @@ TEST_F(FileSystemTest, TempFiles) {
"abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
"abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
EXPECT_EQ(fs::createUniqueFile(Twine(Path270), FileDescriptor, TempPath),
- windows_error::path_not_found);
+ errc::no_such_file_or_directory);
#endif
}
+TEST_F(FileSystemTest, CreateDir) {
+ ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
+ ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
+ ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false),
+ errc::file_exists);
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo"));
+}
+
TEST_F(FileSystemTest, DirectoryIteration) {
- error_code ec;
+ std::error_code ec;
for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec))
ASSERT_NO_ERROR(ec);
// Create a known hierarchy to recurse over.
- bool existed;
- ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
- + "/recursive/a0/aa1", existed));
- ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
- + "/recursive/a0/ab1", existed));
- ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
- + "/recursive/dontlookhere/da1", existed));
- ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
- + "/recursive/z0/za1", existed));
- ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
- + "/recursive/pop/p1", existed));
+ ASSERT_NO_ERROR(
+ fs::create_directories(Twine(TestDirectory) + "/recursive/a0/aa1"));
+ ASSERT_NO_ERROR(
+ fs::create_directories(Twine(TestDirectory) + "/recursive/a0/ab1"));
+ ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) +
+ "/recursive/dontlookhere/da1"));
+ ASSERT_NO_ERROR(
+ fs::create_directories(Twine(TestDirectory) + "/recursive/z0/za1"));
+ ASSERT_NO_ERROR(
+ fs::create_directories(Twine(TestDirectory) + "/recursive/pop/p1"));
typedef std::vector<std::string> v_t;
v_t visited;
for (fs::recursive_directory_iterator i(Twine(TestDirectory)
@@ -414,6 +468,18 @@ TEST_F(FileSystemTest, DirectoryIteration) {
ASSERT_LT(a0, aa1);
ASSERT_LT(a0, ab1);
ASSERT_LT(z0, za1);
+
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/aa1"));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/ab1"));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0"));
+ ASSERT_NO_ERROR(
+ fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere/da1"));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere"));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop/p1"));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop"));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0/za1"));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0"));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive"));
}
const char archive[] = "!<arch>\x0A";
@@ -470,15 +536,13 @@ TEST_F(FileSystemTest, Magic) {
SmallString<128> file_pathname(TestDirectory);
path::append(file_pathname, i->filename);
std::string ErrMsg;
- raw_fd_ostream file(file_pathname.c_str(), ErrMsg, sys::fs::F_Binary);
+ raw_fd_ostream file(file_pathname.c_str(), ErrMsg, sys::fs::F_None);
ASSERT_FALSE(file.has_error());
StringRef magic(i->magic_str, i->magic_str_len);
file << magic;
file.close();
- bool res = false;
- ASSERT_NO_ERROR(fs::has_magic(file_pathname.c_str(), magic, res));
- EXPECT_TRUE(res);
EXPECT_EQ(i->magic, fs::identify_magic(magic));
+ ASSERT_NO_ERROR(fs::remove(Twine(file_pathname)));
}
}
@@ -489,26 +553,27 @@ TEST_F(FileSystemTest, CarriageReturn) {
path::append(FilePathname, "test");
{
- raw_fd_ostream File(FilePathname.c_str(), ErrMsg);
+ raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_Text);
EXPECT_EQ(ErrMsg, "");
File << '\n';
}
{
- OwningPtr<MemoryBuffer> Buf;
- MemoryBuffer::getFile(FilePathname.c_str(), Buf);
- EXPECT_EQ(Buf->getBuffer(), "\r\n");
+ auto Buf = MemoryBuffer::getFile(FilePathname.c_str());
+ EXPECT_TRUE((bool)Buf);
+ EXPECT_EQ(Buf.get()->getBuffer(), "\r\n");
}
{
- raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_Binary);
+ raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_None);
EXPECT_EQ(ErrMsg, "");
File << '\n';
}
{
- OwningPtr<MemoryBuffer> Buf;
- MemoryBuffer::getFile(FilePathname.c_str(), Buf);
- EXPECT_EQ(Buf->getBuffer(), "\n");
+ auto Buf = MemoryBuffer::getFile(FilePathname.c_str());
+ EXPECT_TRUE((bool)Buf);
+ EXPECT_EQ(Buf.get()->getBuffer(), "\n");
}
+ ASSERT_NO_ERROR(fs::remove(Twine(FilePathname)));
}
#endif
@@ -519,7 +584,7 @@ TEST_F(FileSystemTest, FileMapping) {
ASSERT_NO_ERROR(
fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
// Map in temp file and add some content
- error_code EC;
+ std::error_code EC;
StringRef Val("hello there");
{
fs::mapped_file_region mfr(FileDescriptor,
@@ -548,7 +613,6 @@ TEST_F(FileSystemTest, FileMapping) {
// Unmap temp file
-#if LLVM_HAS_RVALUE_REFERENCES
fs::mapped_file_region m(Twine(TempPath),
fs::mapped_file_region::readonly,
0,
@@ -556,8 +620,44 @@ TEST_F(FileSystemTest, FileMapping) {
EC);
ASSERT_NO_ERROR(EC);
const char *Data = m.const_data();
- fs::mapped_file_region mfrrv(llvm_move(m));
+ fs::mapped_file_region mfrrv(std::move(m));
EXPECT_EQ(mfrrv.const_data(), Data);
+}
+
+TEST(Support, NormalizePath) {
+#if defined(LLVM_ON_WIN32)
+#define EXPECT_PATH_IS(path__, windows__, not_windows__) \
+ EXPECT_EQ(path__, windows__);
+#else
+#define EXPECT_PATH_IS(path__, windows__, not_windows__) \
+ EXPECT_EQ(path__, not_windows__);
#endif
+
+ SmallString<64> Path1("a");
+ SmallString<64> Path2("a/b");
+ SmallString<64> Path3("a\\b");
+ SmallString<64> Path4("a\\\\b");
+ SmallString<64> Path5("\\a");
+ SmallString<64> Path6("a\\");
+
+ ASSERT_NO_ERROR(fs::normalize_separators(Path1));
+ EXPECT_PATH_IS(Path1, "a", "a");
+
+ ASSERT_NO_ERROR(fs::normalize_separators(Path2));
+ EXPECT_PATH_IS(Path2, "a/b", "a/b");
+
+ ASSERT_NO_ERROR(fs::normalize_separators(Path3));
+ EXPECT_PATH_IS(Path3, "a\\b", "a/b");
+
+ ASSERT_NO_ERROR(fs::normalize_separators(Path4));
+ EXPECT_PATH_IS(Path4, "a\\\\b", "a\\\\b");
+
+ ASSERT_NO_ERROR(fs::normalize_separators(Path5));
+ EXPECT_PATH_IS(Path5, "\\a", "/a");
+
+ ASSERT_NO_ERROR(fs::normalize_separators(Path6));
+ EXPECT_PATH_IS(Path6, "a\\", "a/");
+
+#undef EXPECT_PATH_IS
}
} // anonymous namespace
diff --git a/unittests/Support/ProcessTest.cpp b/unittests/Support/ProcessTest.cpp
index 27c2318215d6..f4060720961b 100644
--- a/unittests/Support/ProcessTest.cpp
+++ b/unittests/Support/ProcessTest.cpp
@@ -11,7 +11,7 @@
#include "gtest/gtest.h"
#ifdef LLVM_ON_WIN32
-#include "windows.h"
+#include <windows.h>
#endif
namespace {
@@ -39,6 +39,13 @@ TEST(ProcessTest, SelfProcess) {
EXPECT_GT(TimeValue::MaxTime, process::get_self()->get_wall_time());
}
+TEST(ProcessTest, GetRandomNumberTest) {
+ const unsigned r1 = Process::GetRandomNumber();
+ const unsigned r2 = Process::GetRandomNumber();
+ // It should be extremely unlikely that both r1 and r2 are 0.
+ EXPECT_NE((r1 | r2), 0u);
+}
+
#ifdef _MSC_VER
#define setenv(name, var, ignore) _putenv_s(name, var)
#endif
diff --git a/unittests/Support/ProgramTest.cpp b/unittests/Support/ProgramTest.cpp
index 6eb990f29d2a..4e7316fb3ace 100644
--- a/unittests/Support/ProgramTest.cpp
+++ b/unittests/Support/ProgramTest.cpp
@@ -12,7 +12,6 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "gtest/gtest.h"
-
#include <stdlib.h>
#if defined(__APPLE__)
# include <crt_externs.h>
@@ -55,7 +54,7 @@ static void CopyEnvironment(std::vector<const char *> &out) {
// environ seems to work for Windows and most other Unices.
char **envp = environ;
#endif
- while (*envp != 0) {
+ while (*envp != nullptr) {
out.push_back(*envp);
++envp;
}
@@ -77,14 +76,14 @@ TEST(ProgramTest, CreateProcessTrailingSlash) {
"--gtest_filter=ProgramTest.CreateProcessTrailingSlash",
"-program-test-string-arg1", "has\\\\ trailing\\",
"-program-test-string-arg2", "has\\\\ trailing\\",
- 0
+ nullptr
};
// Add LLVM_PROGRAM_TEST_CHILD to the environment of the child.
std::vector<const char *> envp;
CopyEnvironment(envp);
envp.push_back("LLVM_PROGRAM_TEST_CHILD=1");
- envp.push_back(0);
+ envp.push_back(nullptr);
std::string error;
bool ExecutionFailed;
@@ -94,7 +93,7 @@ TEST(ProgramTest, CreateProcessTrailingSlash) {
#else
StringRef nul("/dev/null");
#endif
- const StringRef *redirects[] = { &nul, &nul, 0 };
+ const StringRef *redirects[] = { &nul, &nul, nullptr };
int rc = ExecuteAndWait(my_exe, argv, &envp[0], redirects,
/*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &error,
&ExecutionFailed);
@@ -115,19 +114,19 @@ TEST(ProgramTest, TestExecuteNoWait) {
const char *argv[] = {
Executable.c_str(),
"--gtest_filter=ProgramTest.TestExecuteNoWait",
- 0
+ nullptr
};
// Add LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT to the environment of the child.
std::vector<const char *> envp;
CopyEnvironment(envp);
envp.push_back("LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT=1");
- envp.push_back(0);
+ envp.push_back(nullptr);
std::string Error;
bool ExecutionFailed;
- ProcessInfo PI1 =
- ExecuteNoWait(Executable, argv, &envp[0], 0, 0, &Error, &ExecutionFailed);
+ ProcessInfo PI1 = ExecuteNoWait(Executable, argv, &envp[0], nullptr, 0,
+ &Error, &ExecutionFailed);
ASSERT_FALSE(ExecutionFailed) << Error;
ASSERT_NE(PI1.Pid, 0) << "Invalid process id";
@@ -145,8 +144,8 @@ TEST(ProgramTest, TestExecuteNoWait) {
EXPECT_EQ(LoopCount, 1u) << "LoopCount should be 1";
- ProcessInfo PI2 =
- ExecuteNoWait(Executable, argv, &envp[0], 0, 0, &Error, &ExecutionFailed);
+ ProcessInfo PI2 = ExecuteNoWait(Executable, argv, &envp[0], nullptr, 0,
+ &Error, &ExecutionFailed);
ASSERT_FALSE(ExecutionFailed) << Error;
ASSERT_NE(PI2.Pid, 0) << "Invalid process id";
@@ -163,15 +162,45 @@ TEST(ProgramTest, TestExecuteNoWait) {
ASSERT_GT(LoopCount, 1u) << "LoopCount should be >1";
}
+TEST(ProgramTest, TestExecuteAndWaitTimeout) {
+ using namespace llvm::sys;
+
+ if (getenv("LLVM_PROGRAM_TEST_TIMEOUT")) {
+ sleep_for(/*seconds*/ 10);
+ exit(0);
+ }
+
+ std::string Executable =
+ sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+ const char *argv[] = {
+ Executable.c_str(),
+ "--gtest_filter=ProgramTest.TestExecuteAndWaitTimeout",
+ nullptr
+ };
+
+ // Add LLVM_PROGRAM_TEST_TIMEOUT to the environment of the child.
+ std::vector<const char *> envp;
+ CopyEnvironment(envp);
+ envp.push_back("LLVM_PROGRAM_TEST_TIMEOUT=1");
+ envp.push_back(nullptr);
+
+ std::string Error;
+ bool ExecutionFailed;
+ int RetCode =
+ ExecuteAndWait(Executable, argv, &envp[0], nullptr, /*secondsToWait=*/1, 0,
+ &Error, &ExecutionFailed);
+ ASSERT_EQ(-2, RetCode);
+}
+
TEST(ProgramTest, TestExecuteNegative) {
std::string Executable = "i_dont_exist";
- const char *argv[] = { Executable.c_str(), 0 };
+ const char *argv[] = { Executable.c_str(), nullptr };
{
std::string Error;
bool ExecutionFailed;
- int RetCode =
- ExecuteAndWait(Executable, argv, 0, 0, 0, 0, &Error, &ExecutionFailed);
+ int RetCode = ExecuteAndWait(Executable, argv, nullptr, nullptr, 0, 0,
+ &Error, &ExecutionFailed);
ASSERT_TRUE(RetCode < 0) << "On error ExecuteAndWait should return 0 or "
"positive value indicating the result code";
ASSERT_TRUE(ExecutionFailed);
@@ -181,8 +210,8 @@ TEST(ProgramTest, TestExecuteNegative) {
{
std::string Error;
bool ExecutionFailed;
- ProcessInfo PI =
- ExecuteNoWait(Executable, argv, 0, 0, 0, &Error, &ExecutionFailed);
+ ProcessInfo PI = ExecuteNoWait(Executable, argv, nullptr, nullptr, 0,
+ &Error, &ExecutionFailed);
ASSERT_EQ(PI.Pid, 0)
<< "On error ExecuteNoWait should return an invalid ProcessInfo";
ASSERT_TRUE(ExecutionFailed);
diff --git a/unittests/Support/RegexTest.cpp b/unittests/Support/RegexTest.cpp
index 7b977f744668..c045c49bc3d7 100644
--- a/unittests/Support/RegexTest.cpp
+++ b/unittests/Support/RegexTest.cpp
@@ -90,23 +90,23 @@ TEST_F(RegexTest, Substitution) {
// Standard Escapes
EXPECT_EQ("a\\ber", Regex("[0-9]+").sub("\\\\", "a1234ber", &Error));
- EXPECT_EQ(Error, "");
+ EXPECT_EQ("", Error);
EXPECT_EQ("a\nber", Regex("[0-9]+").sub("\\n", "a1234ber", &Error));
- EXPECT_EQ(Error, "");
+ EXPECT_EQ("", Error);
EXPECT_EQ("a\tber", Regex("[0-9]+").sub("\\t", "a1234ber", &Error));
- EXPECT_EQ(Error, "");
+ EXPECT_EQ("", Error);
EXPECT_EQ("ajber", Regex("[0-9]+").sub("\\j", "a1234ber", &Error));
- EXPECT_EQ(Error, "");
+ EXPECT_EQ("", Error);
EXPECT_EQ("aber", Regex("[0-9]+").sub("\\", "a1234ber", &Error));
EXPECT_EQ(Error, "replacement string contained trailing backslash");
// Backreferences
EXPECT_EQ("aa1234bber", Regex("a[0-9]+b").sub("a\\0b", "a1234ber", &Error));
- EXPECT_EQ(Error, "");
+ EXPECT_EQ("", Error);
EXPECT_EQ("a1234ber", Regex("a([0-9]+)b").sub("a\\1b", "a1234ber", &Error));
- EXPECT_EQ(Error, "");
+ EXPECT_EQ("", Error);
EXPECT_EQ("aber", Regex("a[0-9]+b").sub("a\\100b", "a1234ber", &Error));
EXPECT_EQ(Error, "invalid backreference string '100'");
@@ -127,6 +127,11 @@ TEST_F(RegexTest, IsLiteralERE) {
EXPECT_FALSE(Regex::isLiteralERE("abc{1,2}"));
}
+TEST_F(RegexTest, Escape) {
+ EXPECT_EQ("a\\[bc\\]", Regex::escape("a[bc]"));
+ EXPECT_EQ("abc\\{1\\\\,2\\}", Regex::escape("abc{1\\,2}"));
+}
+
TEST_F(RegexTest, IsValid) {
std::string Error;
EXPECT_FALSE(Regex("(foo").isValid(Error));
@@ -135,4 +140,17 @@ TEST_F(RegexTest, IsValid) {
EXPECT_EQ("invalid character range", Error);
}
+TEST_F(RegexTest, MoveConstruct) {
+ Regex r1("^[0-9]+$");
+ Regex r2(std::move(r1));
+ EXPECT_TRUE(r2.match("916"));
+}
+
+TEST_F(RegexTest, MoveAssign) {
+ Regex r1("^[0-9]+$");
+ Regex r2("abc");
+ r2 = std::move(r1);
+ EXPECT_TRUE(r2.match("916"));
+}
+
}
diff --git a/unittests/Support/ScaledNumberTest.cpp b/unittests/Support/ScaledNumberTest.cpp
new file mode 100644
index 000000000000..7bbef7e4e58d
--- /dev/null
+++ b/unittests/Support/ScaledNumberTest.cpp
@@ -0,0 +1,536 @@
+//===- llvm/unittest/Support/ScaledNumberTest.cpp - ScaledPair tests -----==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ScaledNumber.h"
+
+#include "llvm/Support/DataTypes.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::ScaledNumbers;
+
+namespace {
+
+template <class UIntT> struct ScaledPair {
+ UIntT D;
+ int S;
+ ScaledPair(const std::pair<UIntT, int16_t> &F) : D(F.first), S(F.second) {}
+ ScaledPair(UIntT D, int S) : D(D), S(S) {}
+
+ bool operator==(const ScaledPair<UIntT> &X) const {
+ return D == X.D && S == X.S;
+ }
+};
+template <class UIntT>
+bool operator==(const std::pair<UIntT, int16_t> &L,
+ const ScaledPair<UIntT> &R) {
+ return ScaledPair<UIntT>(L) == R;
+}
+template <class UIntT>
+void PrintTo(const ScaledPair<UIntT> &F, ::std::ostream *os) {
+ *os << F.D << "*2^" << F.S;
+}
+
+typedef ScaledPair<uint32_t> SP32;
+typedef ScaledPair<uint64_t> SP64;
+
+TEST(ScaledNumberHelpersTest, getRounded) {
+ EXPECT_EQ(getRounded32(0, 0, false), SP32(0, 0));
+ EXPECT_EQ(getRounded32(0, 0, true), SP32(1, 0));
+ EXPECT_EQ(getRounded32(20, 21, true), SP32(21, 21));
+ EXPECT_EQ(getRounded32(UINT32_MAX, 0, false), SP32(UINT32_MAX, 0));
+ EXPECT_EQ(getRounded32(UINT32_MAX, 0, true), SP32(1 << 31, 1));
+
+ EXPECT_EQ(getRounded64(0, 0, false), SP64(0, 0));
+ EXPECT_EQ(getRounded64(0, 0, true), SP64(1, 0));
+ EXPECT_EQ(getRounded64(20, 21, true), SP64(21, 21));
+ EXPECT_EQ(getRounded64(UINT32_MAX, 0, false), SP64(UINT32_MAX, 0));
+ EXPECT_EQ(getRounded64(UINT32_MAX, 0, true), SP64(UINT64_C(1) << 32, 0));
+ EXPECT_EQ(getRounded64(UINT64_MAX, 0, false), SP64(UINT64_MAX, 0));
+ EXPECT_EQ(getRounded64(UINT64_MAX, 0, true), SP64(UINT64_C(1) << 63, 1));
+}
+
+TEST(ScaledNumberHelpersTest, getAdjusted) {
+ const uint64_t Max32In64 = UINT32_MAX;
+ EXPECT_EQ(getAdjusted32(0), SP32(0, 0));
+ EXPECT_EQ(getAdjusted32(0, 5), SP32(0, 5));
+ EXPECT_EQ(getAdjusted32(UINT32_MAX), SP32(UINT32_MAX, 0));
+ EXPECT_EQ(getAdjusted32(Max32In64 << 1), SP32(UINT32_MAX, 1));
+ EXPECT_EQ(getAdjusted32(Max32In64 << 1, 1), SP32(UINT32_MAX, 2));
+ EXPECT_EQ(getAdjusted32(Max32In64 << 31), SP32(UINT32_MAX, 31));
+ EXPECT_EQ(getAdjusted32(Max32In64 << 32), SP32(UINT32_MAX, 32));
+ EXPECT_EQ(getAdjusted32(Max32In64 + 1), SP32(1u << 31, 1));
+ EXPECT_EQ(getAdjusted32(UINT64_MAX), SP32(1u << 31, 33));
+
+ EXPECT_EQ(getAdjusted64(0), SP64(0, 0));
+ EXPECT_EQ(getAdjusted64(0, 5), SP64(0, 5));
+ EXPECT_EQ(getAdjusted64(UINT32_MAX), SP64(UINT32_MAX, 0));
+ EXPECT_EQ(getAdjusted64(Max32In64 << 1), SP64(Max32In64 << 1, 0));
+ EXPECT_EQ(getAdjusted64(Max32In64 << 1, 1), SP64(Max32In64 << 1, 1));
+ EXPECT_EQ(getAdjusted64(Max32In64 << 31), SP64(Max32In64 << 31, 0));
+ EXPECT_EQ(getAdjusted64(Max32In64 << 32), SP64(Max32In64 << 32, 0));
+ EXPECT_EQ(getAdjusted64(Max32In64 + 1), SP64(Max32In64 + 1, 0));
+ EXPECT_EQ(getAdjusted64(UINT64_MAX), SP64(UINT64_MAX, 0));
+}
+
+TEST(ScaledNumberHelpersTest, getProduct) {
+ // Zero.
+ EXPECT_EQ(SP32(0, 0), getProduct32(0, 0));
+ EXPECT_EQ(SP32(0, 0), getProduct32(0, 1));
+ EXPECT_EQ(SP32(0, 0), getProduct32(0, 33));
+
+ // Basic.
+ EXPECT_EQ(SP32(6, 0), getProduct32(2, 3));
+ EXPECT_EQ(SP32(UINT16_MAX / 3 * UINT16_MAX / 5 * 2, 0),
+ getProduct32(UINT16_MAX / 3, UINT16_MAX / 5 * 2));
+
+ // Overflow, no loss of precision.
+ // ==> 0xf00010 * 0x1001
+ // ==> 0xf00f00000 + 0x10010
+ // ==> 0xf00f10010
+ // ==> 0xf00f1001 * 2^4
+ EXPECT_EQ(SP32(0xf00f1001, 4), getProduct32(0xf00010, 0x1001));
+
+ // Overflow, loss of precision, rounds down.
+ // ==> 0xf000070 * 0x1001
+ // ==> 0xf00f000000 + 0x70070
+ // ==> 0xf00f070070
+ // ==> 0xf00f0700 * 2^8
+ EXPECT_EQ(SP32(0xf00f0700, 8), getProduct32(0xf000070, 0x1001));
+
+ // Overflow, loss of precision, rounds up.
+ // ==> 0xf000080 * 0x1001
+ // ==> 0xf00f000000 + 0x80080
+ // ==> 0xf00f080080
+ // ==> 0xf00f0801 * 2^8
+ EXPECT_EQ(SP32(0xf00f0801, 8), getProduct32(0xf000080, 0x1001));
+
+ // Reverse operand order.
+ EXPECT_EQ(SP32(0, 0), getProduct32(1, 0));
+ EXPECT_EQ(SP32(0, 0), getProduct32(33, 0));
+ EXPECT_EQ(SP32(6, 0), getProduct32(3, 2));
+ EXPECT_EQ(SP32(UINT16_MAX / 3 * UINT16_MAX / 5 * 2, 0),
+ getProduct32(UINT16_MAX / 5 * 2, UINT16_MAX / 3));
+ EXPECT_EQ(SP32(0xf00f1001, 4), getProduct32(0x1001, 0xf00010));
+ EXPECT_EQ(SP32(0xf00f0700, 8), getProduct32(0x1001, 0xf000070));
+ EXPECT_EQ(SP32(0xf00f0801, 8), getProduct32(0x1001, 0xf000080));
+
+ // Round to overflow.
+ EXPECT_EQ(SP64(UINT64_C(1) << 63, 64),
+ getProduct64(UINT64_C(10376293541461622786),
+ UINT64_C(16397105843297379211)));
+
+ // Big number with rounding.
+ EXPECT_EQ(SP64(UINT64_C(9223372036854775810), 64),
+ getProduct64(UINT64_C(18446744073709551556),
+ UINT64_C(9223372036854775840)));
+}
+
+TEST(ScaledNumberHelpersTest, getQuotient) {
+ // Zero.
+ EXPECT_EQ(SP32(0, 0), getQuotient32(0, 0));
+ EXPECT_EQ(SP32(0, 0), getQuotient32(0, 1));
+ EXPECT_EQ(SP32(0, 0), getQuotient32(0, 73));
+ EXPECT_EQ(SP32(UINT32_MAX, MaxScale), getQuotient32(1, 0));
+ EXPECT_EQ(SP32(UINT32_MAX, MaxScale), getQuotient32(6, 0));
+
+ // Powers of two.
+ EXPECT_EQ(SP32(1u << 31, -31), getQuotient32(1, 1));
+ EXPECT_EQ(SP32(1u << 31, -30), getQuotient32(2, 1));
+ EXPECT_EQ(SP32(1u << 31, -33), getQuotient32(4, 16));
+ EXPECT_EQ(SP32(7u << 29, -29), getQuotient32(7, 1));
+ EXPECT_EQ(SP32(7u << 29, -30), getQuotient32(7, 2));
+ EXPECT_EQ(SP32(7u << 29, -33), getQuotient32(7, 16));
+
+ // Divide evenly.
+ EXPECT_EQ(SP32(3u << 30, -30), getQuotient32(9, 3));
+ EXPECT_EQ(SP32(9u << 28, -28), getQuotient32(63, 7));
+
+ // Divide unevenly.
+ EXPECT_EQ(SP32(0xaaaaaaab, -33), getQuotient32(1, 3));
+ EXPECT_EQ(SP32(0xd5555555, -31), getQuotient32(5, 3));
+
+ // 64-bit division is hard to test, since divide64 doesn't canonicalized its
+ // output. However, this is the algorithm the implementation uses:
+ //
+ // - Shift divisor right.
+ // - If we have 1 (power of 2), return early -- not canonicalized.
+ // - Shift dividend left.
+ // - 64-bit integer divide.
+ // - If there's a remainder, continue with long division.
+ //
+ // TODO: require less knowledge about the implementation in the test.
+
+ // Zero.
+ EXPECT_EQ(SP64(0, 0), getQuotient64(0, 0));
+ EXPECT_EQ(SP64(0, 0), getQuotient64(0, 1));
+ EXPECT_EQ(SP64(0, 0), getQuotient64(0, 73));
+ EXPECT_EQ(SP64(UINT64_MAX, MaxScale), getQuotient64(1, 0));
+ EXPECT_EQ(SP64(UINT64_MAX, MaxScale), getQuotient64(6, 0));
+
+ // Powers of two.
+ EXPECT_EQ(SP64(1, 0), getQuotient64(1, 1));
+ EXPECT_EQ(SP64(2, 0), getQuotient64(2, 1));
+ EXPECT_EQ(SP64(4, -4), getQuotient64(4, 16));
+ EXPECT_EQ(SP64(7, 0), getQuotient64(7, 1));
+ EXPECT_EQ(SP64(7, -1), getQuotient64(7, 2));
+ EXPECT_EQ(SP64(7, -4), getQuotient64(7, 16));
+
+ // Divide evenly.
+ EXPECT_EQ(SP64(UINT64_C(3) << 60, -60), getQuotient64(9, 3));
+ EXPECT_EQ(SP64(UINT64_C(9) << 58, -58), getQuotient64(63, 7));
+
+ // Divide unevenly.
+ EXPECT_EQ(SP64(0xaaaaaaaaaaaaaaab, -65), getQuotient64(1, 3));
+ EXPECT_EQ(SP64(0xd555555555555555, -63), getQuotient64(5, 3));
+}
+
+TEST(ScaledNumberHelpersTest, getLg) {
+ EXPECT_EQ(0, getLg(UINT32_C(1), 0));
+ EXPECT_EQ(1, getLg(UINT32_C(1), 1));
+ EXPECT_EQ(1, getLg(UINT32_C(2), 0));
+ EXPECT_EQ(3, getLg(UINT32_C(1), 3));
+ EXPECT_EQ(3, getLg(UINT32_C(7), 0));
+ EXPECT_EQ(3, getLg(UINT32_C(8), 0));
+ EXPECT_EQ(3, getLg(UINT32_C(9), 0));
+ EXPECT_EQ(3, getLg(UINT32_C(64), -3));
+ EXPECT_EQ(31, getLg((UINT32_MAX >> 1) + 2, 0));
+ EXPECT_EQ(32, getLg(UINT32_MAX, 0));
+ EXPECT_EQ(-1, getLg(UINT32_C(1), -1));
+ EXPECT_EQ(-1, getLg(UINT32_C(2), -2));
+ EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), -1));
+ EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), 0));
+ EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), 1));
+
+ EXPECT_EQ(0, getLg(UINT64_C(1), 0));
+ EXPECT_EQ(1, getLg(UINT64_C(1), 1));
+ EXPECT_EQ(1, getLg(UINT64_C(2), 0));
+ EXPECT_EQ(3, getLg(UINT64_C(1), 3));
+ EXPECT_EQ(3, getLg(UINT64_C(7), 0));
+ EXPECT_EQ(3, getLg(UINT64_C(8), 0));
+ EXPECT_EQ(3, getLg(UINT64_C(9), 0));
+ EXPECT_EQ(3, getLg(UINT64_C(64), -3));
+ EXPECT_EQ(63, getLg((UINT64_MAX >> 1) + 2, 0));
+ EXPECT_EQ(64, getLg(UINT64_MAX, 0));
+ EXPECT_EQ(-1, getLg(UINT64_C(1), -1));
+ EXPECT_EQ(-1, getLg(UINT64_C(2), -2));
+ EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), -1));
+ EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), 0));
+ EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), 1));
+}
+
+TEST(ScaledNumberHelpersTest, getLgFloor) {
+ EXPECT_EQ(0, getLgFloor(UINT32_C(1), 0));
+ EXPECT_EQ(1, getLgFloor(UINT32_C(1), 1));
+ EXPECT_EQ(1, getLgFloor(UINT32_C(2), 0));
+ EXPECT_EQ(2, getLgFloor(UINT32_C(7), 0));
+ EXPECT_EQ(3, getLgFloor(UINT32_C(1), 3));
+ EXPECT_EQ(3, getLgFloor(UINT32_C(8), 0));
+ EXPECT_EQ(3, getLgFloor(UINT32_C(9), 0));
+ EXPECT_EQ(3, getLgFloor(UINT32_C(64), -3));
+ EXPECT_EQ(31, getLgFloor((UINT32_MAX >> 1) + 2, 0));
+ EXPECT_EQ(31, getLgFloor(UINT32_MAX, 0));
+ EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), -1));
+ EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), 0));
+ EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), 1));
+
+ EXPECT_EQ(0, getLgFloor(UINT64_C(1), 0));
+ EXPECT_EQ(1, getLgFloor(UINT64_C(1), 1));
+ EXPECT_EQ(1, getLgFloor(UINT64_C(2), 0));
+ EXPECT_EQ(2, getLgFloor(UINT64_C(7), 0));
+ EXPECT_EQ(3, getLgFloor(UINT64_C(1), 3));
+ EXPECT_EQ(3, getLgFloor(UINT64_C(8), 0));
+ EXPECT_EQ(3, getLgFloor(UINT64_C(9), 0));
+ EXPECT_EQ(3, getLgFloor(UINT64_C(64), -3));
+ EXPECT_EQ(63, getLgFloor((UINT64_MAX >> 1) + 2, 0));
+ EXPECT_EQ(63, getLgFloor(UINT64_MAX, 0));
+ EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), -1));
+ EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), 0));
+ EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), 1));
+}
+
+TEST(ScaledNumberHelpersTest, getLgCeiling) {
+ EXPECT_EQ(0, getLgCeiling(UINT32_C(1), 0));
+ EXPECT_EQ(1, getLgCeiling(UINT32_C(1), 1));
+ EXPECT_EQ(1, getLgCeiling(UINT32_C(2), 0));
+ EXPECT_EQ(3, getLgCeiling(UINT32_C(1), 3));
+ EXPECT_EQ(3, getLgCeiling(UINT32_C(7), 0));
+ EXPECT_EQ(3, getLgCeiling(UINT32_C(8), 0));
+ EXPECT_EQ(3, getLgCeiling(UINT32_C(64), -3));
+ EXPECT_EQ(4, getLgCeiling(UINT32_C(9), 0));
+ EXPECT_EQ(32, getLgCeiling(UINT32_MAX, 0));
+ EXPECT_EQ(32, getLgCeiling((UINT32_MAX >> 1) + 2, 0));
+ EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), -1));
+ EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), 0));
+ EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), 1));
+
+ EXPECT_EQ(0, getLgCeiling(UINT64_C(1), 0));
+ EXPECT_EQ(1, getLgCeiling(UINT64_C(1), 1));
+ EXPECT_EQ(1, getLgCeiling(UINT64_C(2), 0));
+ EXPECT_EQ(3, getLgCeiling(UINT64_C(1), 3));
+ EXPECT_EQ(3, getLgCeiling(UINT64_C(7), 0));
+ EXPECT_EQ(3, getLgCeiling(UINT64_C(8), 0));
+ EXPECT_EQ(3, getLgCeiling(UINT64_C(64), -3));
+ EXPECT_EQ(4, getLgCeiling(UINT64_C(9), 0));
+ EXPECT_EQ(64, getLgCeiling((UINT64_MAX >> 1) + 2, 0));
+ EXPECT_EQ(64, getLgCeiling(UINT64_MAX, 0));
+ EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), -1));
+ EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), 0));
+ EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), 1));
+}
+
+TEST(ScaledNumberHelpersTest, compare) {
+ EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), 1));
+ EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), -10));
+ EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), 20));
+ EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(64), -3));
+ EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(32), -2));
+ EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(16), -1));
+ EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(8), 0));
+ EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(4), 1));
+ EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(2), 2));
+ EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(1), 3));
+ EXPECT_EQ(-1, compare(UINT32_C(0), 0, UINT32_C(1), 3));
+ EXPECT_EQ(-1, compare(UINT32_C(7), 0, UINT32_C(1), 3));
+ EXPECT_EQ(-1, compare(UINT32_C(7), 0, UINT32_C(64), -3));
+ EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(1), 3));
+ EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(64), -3));
+ EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(0), 0));
+
+ EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), 1));
+ EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), -10));
+ EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), 20));
+ EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(64), -3));
+ EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(32), -2));
+ EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(16), -1));
+ EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(8), 0));
+ EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(4), 1));
+ EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(2), 2));
+ EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(1), 3));
+ EXPECT_EQ(-1, compare(UINT64_C(0), 0, UINT64_C(1), 3));
+ EXPECT_EQ(-1, compare(UINT64_C(7), 0, UINT64_C(1), 3));
+ EXPECT_EQ(-1, compare(UINT64_C(7), 0, UINT64_C(64), -3));
+ EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(1), 3));
+ EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(64), -3));
+ EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(0), 0));
+ EXPECT_EQ(-1, compare(UINT64_MAX, 0, UINT64_C(1), 64));
+}
+
+TEST(ScaledNumberHelpersTest, matchScales) {
+#define MATCH_SCALES(T, LDIn, LSIn, RDIn, RSIn, LDOut, RDOut, SOut) \
+ do { \
+ T LDx = LDIn; \
+ T RDx = RDIn; \
+ T LDy = LDOut; \
+ T RDy = RDOut; \
+ int16_t LSx = LSIn; \
+ int16_t RSx = RSIn; \
+ int16_t Sy = SOut; \
+ \
+ EXPECT_EQ(SOut, matchScales(LDx, LSx, RDx, RSx)); \
+ EXPECT_EQ(LDy, LDx); \
+ EXPECT_EQ(RDy, RDx); \
+ if (LDy) \
+ EXPECT_EQ(Sy, LSx); \
+ if (RDy) \
+ EXPECT_EQ(Sy, RSx); \
+ } while (false)
+
+ MATCH_SCALES(uint32_t, 0, 0, 0, 0, 0, 0, 0);
+ MATCH_SCALES(uint32_t, 0, 50, 7, 1, 0, 7, 1);
+ MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 1, 9, 0, UINT32_C(1) << 31, 4, 1);
+ MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 2, 9, 0, UINT32_C(1) << 31, 2, 2);
+ MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 3, 9, 0, UINT32_C(1) << 31, 1, 3);
+ MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 4, 9, 0, UINT32_C(1) << 31, 0, 4);
+ MATCH_SCALES(uint32_t, UINT32_C(1) << 30, 4, 9, 0, UINT32_C(1) << 31, 1, 3);
+ MATCH_SCALES(uint32_t, UINT32_C(1) << 29, 4, 9, 0, UINT32_C(1) << 31, 2, 2);
+ MATCH_SCALES(uint32_t, UINT32_C(1) << 28, 4, 9, 0, UINT32_C(1) << 31, 4, 1);
+ MATCH_SCALES(uint32_t, UINT32_C(1) << 27, 4, 9, 0, UINT32_C(1) << 31, 9, 0);
+ MATCH_SCALES(uint32_t, 7, 1, 0, 50, 7, 0, 1);
+ MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 1, 4, UINT32_C(1) << 31, 1);
+ MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 2, 2, UINT32_C(1) << 31, 2);
+ MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 3, 1, UINT32_C(1) << 31, 3);
+ MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 4, 0, UINT32_C(1) << 31, 4);
+ MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 30, 4, 1, UINT32_C(1) << 31, 3);
+ MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 29, 4, 2, UINT32_C(1) << 31, 2);
+ MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 28, 4, 4, UINT32_C(1) << 31, 1);
+ MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 27, 4, 9, UINT32_C(1) << 31, 0);
+
+ MATCH_SCALES(uint64_t, 0, 0, 0, 0, 0, 0, 0);
+ MATCH_SCALES(uint64_t, 0, 100, 7, 1, 0, 7, 1);
+ MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 1, 9, 0, UINT64_C(1) << 63, 4, 1);
+ MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 2, 9, 0, UINT64_C(1) << 63, 2, 2);
+ MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 3, 9, 0, UINT64_C(1) << 63, 1, 3);
+ MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 4, 9, 0, UINT64_C(1) << 63, 0, 4);
+ MATCH_SCALES(uint64_t, UINT64_C(1) << 62, 4, 9, 0, UINT64_C(1) << 63, 1, 3);
+ MATCH_SCALES(uint64_t, UINT64_C(1) << 61, 4, 9, 0, UINT64_C(1) << 63, 2, 2);
+ MATCH_SCALES(uint64_t, UINT64_C(1) << 60, 4, 9, 0, UINT64_C(1) << 63, 4, 1);
+ MATCH_SCALES(uint64_t, UINT64_C(1) << 59, 4, 9, 0, UINT64_C(1) << 63, 9, 0);
+ MATCH_SCALES(uint64_t, 7, 1, 0, 100, 7, 0, 1);
+ MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 1, 4, UINT64_C(1) << 63, 1);
+ MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 2, 2, UINT64_C(1) << 63, 2);
+ MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 3, 1, UINT64_C(1) << 63, 3);
+ MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 4, 0, UINT64_C(1) << 63, 4);
+ MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 62, 4, 1, UINT64_C(1) << 63, 3);
+ MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 61, 4, 2, UINT64_C(1) << 63, 2);
+ MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 60, 4, 4, UINT64_C(1) << 63, 1);
+ MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 59, 4, 9, UINT64_C(1) << 63, 0);
+}
+
+TEST(ScaledNumberHelpersTest, getSum) {
+ // Zero.
+ EXPECT_EQ(SP32(1, 0), getSum32(0, 0, 1, 0));
+ EXPECT_EQ(SP32(8, -3), getSum32(0, 0, 8, -3));
+ EXPECT_EQ(SP32(UINT32_MAX, 0), getSum32(0, 0, UINT32_MAX, 0));
+
+ // Basic.
+ EXPECT_EQ(SP32(2, 0), getSum32(1, 0, 1, 0));
+ EXPECT_EQ(SP32(3, 0), getSum32(1, 0, 2, 0));
+ EXPECT_EQ(SP32(67, 0), getSum32(7, 0, 60, 0));
+
+ // Different scales.
+ EXPECT_EQ(SP32(3, 0), getSum32(1, 0, 1, 1));
+ EXPECT_EQ(SP32(4, 0), getSum32(2, 0, 1, 1));
+
+ // Loss of precision.
+ EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 32, 1, 0));
+ EXPECT_EQ(SP32(UINT32_C(1) << 31, -31), getSum32(1, -32, 1, 0));
+
+ // Not quite loss of precision.
+ EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), getSum32(1, 32, 1, 1));
+ EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -32), getSum32(1, -32, 1, -1));
+
+ // Overflow.
+ EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 0, UINT32_MAX, 0));
+
+ // Reverse operand order.
+ EXPECT_EQ(SP32(1, 0), getSum32(1, 0, 0, 0));
+ EXPECT_EQ(SP32(8, -3), getSum32(8, -3, 0, 0));
+ EXPECT_EQ(SP32(UINT32_MAX, 0), getSum32(UINT32_MAX, 0, 0, 0));
+ EXPECT_EQ(SP32(3, 0), getSum32(2, 0, 1, 0));
+ EXPECT_EQ(SP32(67, 0), getSum32(60, 0, 7, 0));
+ EXPECT_EQ(SP32(3, 0), getSum32(1, 1, 1, 0));
+ EXPECT_EQ(SP32(4, 0), getSum32(1, 1, 2, 0));
+ EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 0, 1, 32));
+ EXPECT_EQ(SP32(UINT32_C(1) << 31, -31), getSum32(1, 0, 1, -32));
+ EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), getSum32(1, 1, 1, 32));
+ EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -32), getSum32(1, -1, 1, -32));
+ EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(UINT32_MAX, 0, 1, 0));
+
+ // Zero.
+ EXPECT_EQ(SP64(1, 0), getSum64(0, 0, 1, 0));
+ EXPECT_EQ(SP64(8, -3), getSum64(0, 0, 8, -3));
+ EXPECT_EQ(SP64(UINT64_MAX, 0), getSum64(0, 0, UINT64_MAX, 0));
+
+ // Basic.
+ EXPECT_EQ(SP64(2, 0), getSum64(1, 0, 1, 0));
+ EXPECT_EQ(SP64(3, 0), getSum64(1, 0, 2, 0));
+ EXPECT_EQ(SP64(67, 0), getSum64(7, 0, 60, 0));
+
+ // Different scales.
+ EXPECT_EQ(SP64(3, 0), getSum64(1, 0, 1, 1));
+ EXPECT_EQ(SP64(4, 0), getSum64(2, 0, 1, 1));
+
+ // Loss of precision.
+ EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 64, 1, 0));
+ EXPECT_EQ(SP64(UINT64_C(1) << 63, -63), getSum64(1, -64, 1, 0));
+
+ // Not quite loss of precision.
+ EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), getSum64(1, 64, 1, 1));
+ EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -64), getSum64(1, -64, 1, -1));
+
+ // Overflow.
+ EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 0, UINT64_MAX, 0));
+
+ // Reverse operand order.
+ EXPECT_EQ(SP64(1, 0), getSum64(1, 0, 0, 0));
+ EXPECT_EQ(SP64(8, -3), getSum64(8, -3, 0, 0));
+ EXPECT_EQ(SP64(UINT64_MAX, 0), getSum64(UINT64_MAX, 0, 0, 0));
+ EXPECT_EQ(SP64(3, 0), getSum64(2, 0, 1, 0));
+ EXPECT_EQ(SP64(67, 0), getSum64(60, 0, 7, 0));
+ EXPECT_EQ(SP64(3, 0), getSum64(1, 1, 1, 0));
+ EXPECT_EQ(SP64(4, 0), getSum64(1, 1, 2, 0));
+ EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 0, 1, 64));
+ EXPECT_EQ(SP64(UINT64_C(1) << 63, -63), getSum64(1, 0, 1, -64));
+ EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), getSum64(1, 1, 1, 64));
+ EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -64), getSum64(1, -1, 1, -64));
+ EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(UINT64_MAX, 0, 1, 0));
+}
+
+TEST(ScaledNumberHelpersTest, getDifference) {
+ // Basic.
+ EXPECT_EQ(SP32(0, 0), getDifference32(1, 0, 1, 0));
+ EXPECT_EQ(SP32(1, 0), getDifference32(2, 0, 1, 0));
+ EXPECT_EQ(SP32(53, 0), getDifference32(60, 0, 7, 0));
+
+ // Equals "0", different scales.
+ EXPECT_EQ(SP32(0, 0), getDifference32(2, 0, 1, 1));
+
+ // Subtract "0".
+ EXPECT_EQ(SP32(1, 0), getDifference32(1, 0, 0, 0));
+ EXPECT_EQ(SP32(8, -3), getDifference32(8, -3, 0, 0));
+ EXPECT_EQ(SP32(UINT32_MAX, 0), getDifference32(UINT32_MAX, 0, 0, 0));
+
+ // Loss of precision.
+ EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1),
+ getDifference32((UINT32_C(1) << 31) + 1, 1, 1, 0));
+ EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -31),
+ getDifference32((UINT32_C(1) << 31) + 1, -31, 1, -32));
+
+ // Not quite loss of precision.
+ EXPECT_EQ(SP32(UINT32_MAX, 0), getDifference32(1, 32, 1, 0));
+ EXPECT_EQ(SP32(UINT32_MAX, -32), getDifference32(1, 0, 1, -32));
+
+ // Saturate to "0".
+ EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, 1, 0));
+ EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, 8, -3));
+ EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, UINT32_MAX, 0));
+ EXPECT_EQ(SP32(0, 0), getDifference32(7, 0, 60, 0));
+ EXPECT_EQ(SP32(0, 0), getDifference32(1, 0, 1, 1));
+ EXPECT_EQ(SP32(0, 0), getDifference32(1, -32, 1, 0));
+ EXPECT_EQ(SP32(0, 0), getDifference32(1, -32, 1, -1));
+
+ // Regression tests for cases that failed during bringup.
+ EXPECT_EQ(SP32(UINT32_C(1) << 26, -31),
+ getDifference32(1, 0, UINT32_C(31) << 27, -32));
+
+ // Basic.
+ EXPECT_EQ(SP64(0, 0), getDifference64(1, 0, 1, 0));
+ EXPECT_EQ(SP64(1, 0), getDifference64(2, 0, 1, 0));
+ EXPECT_EQ(SP64(53, 0), getDifference64(60, 0, 7, 0));
+
+ // Equals "0", different scales.
+ EXPECT_EQ(SP64(0, 0), getDifference64(2, 0, 1, 1));
+
+ // Subtract "0".
+ EXPECT_EQ(SP64(1, 0), getDifference64(1, 0, 0, 0));
+ EXPECT_EQ(SP64(8, -3), getDifference64(8, -3, 0, 0));
+ EXPECT_EQ(SP64(UINT64_MAX, 0), getDifference64(UINT64_MAX, 0, 0, 0));
+
+ // Loss of precision.
+ EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1),
+ getDifference64((UINT64_C(1) << 63) + 1, 1, 1, 0));
+ EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -63),
+ getDifference64((UINT64_C(1) << 63) + 1, -63, 1, -64));
+
+ // Not quite loss of precision.
+ EXPECT_EQ(SP64(UINT64_MAX, 0), getDifference64(1, 64, 1, 0));
+ EXPECT_EQ(SP64(UINT64_MAX, -64), getDifference64(1, 0, 1, -64));
+
+ // Saturate to "0".
+ EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, 1, 0));
+ EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, 8, -3));
+ EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, UINT64_MAX, 0));
+ EXPECT_EQ(SP64(0, 0), getDifference64(7, 0, 60, 0));
+ EXPECT_EQ(SP64(0, 0), getDifference64(1, 0, 1, 1));
+ EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, 0));
+ EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, -1));
+}
+
+} // end namespace
diff --git a/unittests/Support/SpecialCaseListTest.cpp b/unittests/Support/SpecialCaseListTest.cpp
new file mode 100644
index 000000000000..bb9c351415bf
--- /dev/null
+++ b/unittests/Support/SpecialCaseListTest.cpp
@@ -0,0 +1,126 @@
+//===- SpecialCaseListTest.cpp - Unit tests for SpecialCaseList -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class SpecialCaseListTest : public ::testing::Test {
+protected:
+ SpecialCaseList *makeSpecialCaseList(StringRef List, std::string &Error) {
+ std::unique_ptr<MemoryBuffer> MB(MemoryBuffer::getMemBuffer(List));
+ return SpecialCaseList::create(MB.get(), Error);
+ }
+
+ SpecialCaseList *makeSpecialCaseList(StringRef List) {
+ std::string Error;
+ SpecialCaseList *SCL = makeSpecialCaseList(List, Error);
+ assert(SCL);
+ assert(Error == "");
+ return SCL;
+ }
+};
+
+TEST_F(SpecialCaseListTest, Basic) {
+ std::unique_ptr<SpecialCaseList> SCL(
+ makeSpecialCaseList("# This is a comment.\n"
+ "\n"
+ "src:hello\n"
+ "src:bye\n"
+ "src:hi=category\n"
+ "src:z*=category\n"));
+ EXPECT_TRUE(SCL->inSection("src", "hello"));
+ EXPECT_TRUE(SCL->inSection("src", "bye"));
+ EXPECT_TRUE(SCL->inSection("src", "hi", "category"));
+ EXPECT_TRUE(SCL->inSection("src", "zzzz", "category"));
+ EXPECT_FALSE(SCL->inSection("src", "hi"));
+ EXPECT_FALSE(SCL->inSection("fun", "hello"));
+ EXPECT_FALSE(SCL->inSection("src", "hello", "category"));
+}
+
+TEST_F(SpecialCaseListTest, GlobalInitCompat) {
+ std::unique_ptr<SpecialCaseList> SCL(
+ makeSpecialCaseList("global:foo=init\n"));
+ EXPECT_FALSE(SCL->inSection("global", "foo"));
+ EXPECT_FALSE(SCL->inSection("global", "bar"));
+ EXPECT_TRUE(SCL->inSection("global", "foo", "init"));
+ EXPECT_FALSE(SCL->inSection("global", "bar", "init"));
+
+ SCL.reset(makeSpecialCaseList("global-init:foo\n"));
+ EXPECT_FALSE(SCL->inSection("global", "foo"));
+ EXPECT_FALSE(SCL->inSection("global", "bar"));
+ EXPECT_TRUE(SCL->inSection("global", "foo", "init"));
+ EXPECT_FALSE(SCL->inSection("global", "bar", "init"));
+
+ SCL.reset(makeSpecialCaseList("type:t2=init\n"));
+ EXPECT_FALSE(SCL->inSection("type", "t1"));
+ EXPECT_FALSE(SCL->inSection("type", "t2"));
+ EXPECT_FALSE(SCL->inSection("type", "t1", "init"));
+ EXPECT_TRUE(SCL->inSection("type", "t2", "init"));
+
+ SCL.reset(makeSpecialCaseList("global-init-type:t2\n"));
+ EXPECT_FALSE(SCL->inSection("type", "t1"));
+ EXPECT_FALSE(SCL->inSection("type", "t2"));
+ EXPECT_FALSE(SCL->inSection("type", "t1", "init"));
+ EXPECT_TRUE(SCL->inSection("type", "t2", "init"));
+
+ SCL.reset(makeSpecialCaseList("src:hello=init\n"));
+ EXPECT_FALSE(SCL->inSection("src", "hello"));
+ EXPECT_FALSE(SCL->inSection("src", "bye"));
+ EXPECT_TRUE(SCL->inSection("src", "hello", "init"));
+ EXPECT_FALSE(SCL->inSection("src", "bye", "init"));
+
+ SCL.reset(makeSpecialCaseList("global-init-src:hello\n"));
+ EXPECT_FALSE(SCL->inSection("src", "hello"));
+ EXPECT_FALSE(SCL->inSection("src", "bye"));
+ EXPECT_TRUE(SCL->inSection("src", "hello", "init"));
+ EXPECT_FALSE(SCL->inSection("src", "bye", "init"));
+}
+
+TEST_F(SpecialCaseListTest, Substring) {
+ std::unique_ptr<SpecialCaseList> SCL(makeSpecialCaseList("src:hello\n"
+ "fun:foo\n"
+ "global:bar\n"));
+ EXPECT_FALSE(SCL->inSection("src", "othello"));
+ EXPECT_FALSE(SCL->inSection("fun", "tomfoolery"));
+ EXPECT_FALSE(SCL->inSection("global", "bartender"));
+
+ SCL.reset(makeSpecialCaseList("fun:*foo*\n"));
+ EXPECT_TRUE(SCL->inSection("fun", "tomfoolery"));
+ EXPECT_TRUE(SCL->inSection("fun", "foobar"));
+}
+
+TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
+ std::string Error;
+ EXPECT_EQ(nullptr, makeSpecialCaseList("badline", Error));
+ EXPECT_EQ("Malformed line 1: 'badline'", Error);
+ EXPECT_EQ(nullptr, makeSpecialCaseList("src:bad[a-", Error));
+ EXPECT_EQ("Malformed regex in line 1: 'bad[a-': invalid character range",
+ Error);
+ EXPECT_EQ(nullptr, makeSpecialCaseList("src:a.c\n"
+ "fun:fun(a\n",
+ Error));
+ EXPECT_EQ("Malformed regex in line 2: 'fun(a': parentheses not balanced",
+ Error);
+ EXPECT_EQ(nullptr, SpecialCaseList::create("unexisting", Error));
+ EXPECT_EQ(0U, Error.find("Can't open file 'unexisting':"));
+}
+
+TEST_F(SpecialCaseListTest, EmptySpecialCaseList) {
+ std::unique_ptr<SpecialCaseList> SCL(makeSpecialCaseList(""));
+ EXPECT_FALSE(SCL->inSection("foo", "bar"));
+}
+
+}
+
+
diff --git a/unittests/Support/StringPool.cpp b/unittests/Support/StringPool.cpp
new file mode 100644
index 000000000000..7b7805f91710
--- /dev/null
+++ b/unittests/Support/StringPool.cpp
@@ -0,0 +1,31 @@
+//===- llvm/unittest/Support/ThreadLocalTest.cpp - Therad Local tests ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/StringPool.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(PooledStringPtrTest, OperatorEquals) {
+ StringPool pool;
+ const PooledStringPtr a = pool.intern("a");
+ const PooledStringPtr b = pool.intern("b");
+ EXPECT_FALSE(a == b);
+}
+
+TEST(PooledStringPtrTest, OperatorNotEquals) {
+ StringPool pool;
+ const PooledStringPtr a = pool.intern("a");
+ const PooledStringPtr b = pool.intern("b");
+ EXPECT_TRUE(a != b);
+}
+
+}
diff --git a/unittests/Support/SwapByteOrderTest.cpp b/unittests/Support/SwapByteOrderTest.cpp
index c2a0c2793889..525cfc1aea82 100644
--- a/unittests/Support/SwapByteOrderTest.cpp
+++ b/unittests/Support/SwapByteOrderTest.cpp
@@ -17,73 +17,73 @@ using namespace llvm;
namespace {
-// In these first two tests all of the origional_uintx values are truncated
+// In these first two tests all of the original_uintx values are truncated
// except for 64. We could avoid this, but there's really no point.
-TEST(SwapByteOrder, UnsignedRoundTrip) {
+TEST(getSwappedBytes, UnsignedRoundTrip) {
// The point of the bit twiddling of magic is to test with and without bits
// in every byte.
uint64_t value = 1;
for (std::size_t i = 0; i <= sizeof(value); ++i) {
- uint8_t origional_uint8 = static_cast<uint8_t>(value);
- EXPECT_EQ(origional_uint8,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_uint8)));
+ uint8_t original_uint8 = static_cast<uint8_t>(value);
+ EXPECT_EQ(original_uint8,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_uint8)));
- uint16_t origional_uint16 = static_cast<uint16_t>(value);
- EXPECT_EQ(origional_uint16,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_uint16)));
+ uint16_t original_uint16 = static_cast<uint16_t>(value);
+ EXPECT_EQ(original_uint16,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_uint16)));
- uint32_t origional_uint32 = static_cast<uint32_t>(value);
- EXPECT_EQ(origional_uint32,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_uint32)));
+ uint32_t original_uint32 = static_cast<uint32_t>(value);
+ EXPECT_EQ(original_uint32,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_uint32)));
- uint64_t origional_uint64 = static_cast<uint64_t>(value);
- EXPECT_EQ(origional_uint64,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_uint64)));
+ uint64_t original_uint64 = static_cast<uint64_t>(value);
+ EXPECT_EQ(original_uint64,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_uint64)));
value = (value << 8) | 0x55; // binary 0101 0101.
}
}
-TEST(SwapByteOrder, SignedRoundTrip) {
+TEST(getSwappedBytes, SignedRoundTrip) {
// The point of the bit twiddling of magic is to test with and without bits
// in every byte.
uint64_t value = 1;
for (std::size_t i = 0; i <= sizeof(value); ++i) {
- int8_t origional_int8 = static_cast<int8_t>(value);
- EXPECT_EQ(origional_int8,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_int8)));
+ int8_t original_int8 = static_cast<int8_t>(value);
+ EXPECT_EQ(original_int8,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_int8)));
- int16_t origional_int16 = static_cast<int16_t>(value);
- EXPECT_EQ(origional_int16,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_int16)));
+ int16_t original_int16 = static_cast<int16_t>(value);
+ EXPECT_EQ(original_int16,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_int16)));
- int32_t origional_int32 = static_cast<int32_t>(value);
- EXPECT_EQ(origional_int32,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_int32)));
+ int32_t original_int32 = static_cast<int32_t>(value);
+ EXPECT_EQ(original_int32,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_int32)));
- int64_t origional_int64 = static_cast<int64_t>(value);
- EXPECT_EQ(origional_int64,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_int64)));
+ int64_t original_int64 = static_cast<int64_t>(value);
+ EXPECT_EQ(original_int64,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_int64)));
// Test other sign.
value *= -1;
- origional_int8 = static_cast<int8_t>(value);
- EXPECT_EQ(origional_int8,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_int8)));
+ original_int8 = static_cast<int8_t>(value);
+ EXPECT_EQ(original_int8,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_int8)));
- origional_int16 = static_cast<int16_t>(value);
- EXPECT_EQ(origional_int16,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_int16)));
+ original_int16 = static_cast<int16_t>(value);
+ EXPECT_EQ(original_int16,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_int16)));
- origional_int32 = static_cast<int32_t>(value);
- EXPECT_EQ(origional_int32,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_int32)));
+ original_int32 = static_cast<int32_t>(value);
+ EXPECT_EQ(original_int32,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_int32)));
- origional_int64 = static_cast<int64_t>(value);
- EXPECT_EQ(origional_int64,
- sys::SwapByteOrder(sys::SwapByteOrder(origional_int64)));
+ original_int64 = static_cast<int64_t>(value);
+ EXPECT_EQ(original_int64,
+ sys::getSwappedBytes(sys::getSwappedBytes(original_int64)));
// Return to normal sign and twiddle.
value *= -1;
@@ -91,38 +91,86 @@ TEST(SwapByteOrder, SignedRoundTrip) {
}
}
-TEST(SwapByteOrder, uint8_t) {
- EXPECT_EQ(uint8_t(0x11), sys::SwapByteOrder(uint8_t(0x11)));
+TEST(getSwappedBytes, uint8_t) {
+ EXPECT_EQ(uint8_t(0x11), sys::getSwappedBytes(uint8_t(0x11)));
}
-TEST(SwapByteOrder, uint16_t) {
- EXPECT_EQ(uint16_t(0x1122), sys::SwapByteOrder(uint16_t(0x2211)));
+TEST(getSwappedBytes, uint16_t) {
+ EXPECT_EQ(uint16_t(0x1122), sys::getSwappedBytes(uint16_t(0x2211)));
}
-TEST(SwapByteOrder, uint32_t) {
- EXPECT_EQ(uint32_t(0x11223344), sys::SwapByteOrder(uint32_t(0x44332211)));
+TEST(getSwappedBytes, uint32_t) {
+ EXPECT_EQ(uint32_t(0x11223344), sys::getSwappedBytes(uint32_t(0x44332211)));
}
-TEST(SwapByteOrder, uint64_t) {
+TEST(getSwappedBytes, uint64_t) {
EXPECT_EQ(uint64_t(0x1122334455667788ULL),
- sys::SwapByteOrder(uint64_t(0x8877665544332211ULL)));
+ sys::getSwappedBytes(uint64_t(0x8877665544332211ULL)));
}
-TEST(SwapByteOrder, int8_t) {
- EXPECT_EQ(int8_t(0x11), sys::SwapByteOrder(int8_t(0x11)));
+TEST(getSwappedBytes, int8_t) {
+ EXPECT_EQ(int8_t(0x11), sys::getSwappedBytes(int8_t(0x11)));
}
-TEST(SwapByteOrder, int16_t) {
- EXPECT_EQ(int16_t(0x1122), sys::SwapByteOrder(int16_t(0x2211)));
+TEST(getSwappedBytes, int16_t) {
+ EXPECT_EQ(int16_t(0x1122), sys::getSwappedBytes(int16_t(0x2211)));
}
-TEST(SwapByteOrder, int32_t) {
- EXPECT_EQ(int32_t(0x11223344), sys::SwapByteOrder(int32_t(0x44332211)));
+TEST(getSwappedBytes, int32_t) {
+ EXPECT_EQ(int32_t(0x11223344), sys::getSwappedBytes(int32_t(0x44332211)));
}
-TEST(SwapByteOrder, int64_t) {
+TEST(getSwappedBytes, int64_t) {
EXPECT_EQ(int64_t(0x1122334455667788LL),
- sys::SwapByteOrder(int64_t(0x8877665544332211LL)));
+ sys::getSwappedBytes(int64_t(0x8877665544332211LL)));
+}
+
+TEST(swapByteOrder, uint8_t) {
+ uint8_t value = 0x11;
+ sys::swapByteOrder(value);
+ EXPECT_EQ(uint8_t(0x11), value);
+}
+
+TEST(swapByteOrder, uint16_t) {
+ uint16_t value = 0x2211;
+ sys::swapByteOrder(value);
+ EXPECT_EQ(uint16_t(0x1122), value);
+}
+
+TEST(swapByteOrder, uint32_t) {
+ uint32_t value = 0x44332211;
+ sys::swapByteOrder(value);
+ EXPECT_EQ(uint32_t(0x11223344), value);
+}
+
+TEST(swapByteOrder, uint64_t) {
+ uint64_t value = 0x8877665544332211ULL;
+ sys::swapByteOrder(value);
+ EXPECT_EQ(uint64_t(0x1122334455667788ULL), value);
+}
+
+TEST(swapByteOrder, int8_t) {
+ int8_t value = 0x11;
+ sys::swapByteOrder(value);
+ EXPECT_EQ(int8_t(0x11), value);
+}
+
+TEST(swapByteOrder, int16_t) {
+ int16_t value = 0x2211;
+ sys::swapByteOrder(value);
+ EXPECT_EQ(int16_t(0x1122), value);
+}
+
+TEST(swapByteOrder, int32_t) {
+ int32_t value = 0x44332211;
+ sys::swapByteOrder(value);
+ EXPECT_EQ(int32_t(0x11223344), value);
+}
+
+TEST(swapByteOrder, int64_t) {
+ int64_t value = 0x8877665544332211LL;
+ sys::swapByteOrder(value);
+ EXPECT_EQ(int64_t(0x1122334455667788LL), value);
}
}
diff --git a/unittests/Support/ThreadLocalTest.cpp b/unittests/Support/ThreadLocalTest.cpp
index dd4d706f5cf5..ea751be230cc 100644
--- a/unittests/Support/ThreadLocalTest.cpp
+++ b/unittests/Support/ThreadLocalTest.cpp
@@ -25,14 +25,14 @@ struct S {
TEST_F(ThreadLocalTest, Basics) {
ThreadLocal<const S> x;
- EXPECT_EQ(0, x.get());
+ EXPECT_EQ(nullptr, x.get());
S s;
x.set(&s);
EXPECT_EQ(&s, x.get());
x.erase();
- EXPECT_EQ(0, x.get());
+ EXPECT_EQ(nullptr, x.get());
}
}
diff --git a/unittests/Support/TimeValueTest.cpp b/unittests/Support/TimeValueTest.cpp
index fb2abe382932..3d2b9780c069 100644
--- a/unittests/Support/TimeValueTest.cpp
+++ b/unittests/Support/TimeValueTest.cpp
@@ -16,8 +16,8 @@ namespace {
TEST(TimeValue, time_t) {
sys::TimeValue now = sys::TimeValue::now();
- time_t now_t = time(NULL);
- EXPECT_TRUE(abs(static_cast<long>(now_t - now.toEpochTime())) < 2);
+ time_t now_t = time(nullptr);
+ EXPECT_TRUE(std::abs(static_cast<long>(now_t - now.toEpochTime())) < 2);
}
TEST(TimeValue, Win32FILETIME) {
@@ -30,7 +30,8 @@ TEST(TimeValue, Win32FILETIME) {
epoch.fromWin32Time(ft1970);
// The "seconds" part in Posix time may be expected as zero.
- EXPECT_EQ(ns / 100, epoch.toPosixTime());
+ EXPECT_EQ(0u, epoch.toEpochTime());
+ EXPECT_EQ(ns, static_cast<uint32_t>(epoch.nanoseconds()));
// Confirm it reversible.
EXPECT_EQ(ft1970, epoch.toWin32Time());
diff --git a/unittests/Support/YAMLIOTest.cpp b/unittests/Support/YAMLIOTest.cpp
index 6c0b9e6151f2..8aed98012f10 100644
--- a/unittests/Support/YAMLIOTest.cpp
+++ b/unittests/Support/YAMLIOTest.cpp
@@ -27,6 +27,13 @@ using llvm::yaml::Hex32;
using llvm::yaml::Hex64;
+
+
+static void suppressErrorMessages(const llvm::SMDiagnostic &, void *) {
+}
+
+
+
//===----------------------------------------------------------------------===//
// Test MappingTraits
//===----------------------------------------------------------------------===//
@@ -140,6 +147,7 @@ TEST(YAMLIO, TestSequenceMapWriteAndRead) {
struct BuiltInTypes {
llvm::StringRef str;
+ std::string stdstr;
uint64_t u64;
uint32_t u32;
uint16_t u16;
@@ -163,6 +171,7 @@ namespace yaml {
struct MappingTraits<BuiltInTypes> {
static void mapping(IO &io, BuiltInTypes& bt) {
io.mapRequired("str", bt.str);
+ io.mapRequired("stdstr", bt.stdstr);
io.mapRequired("u64", bt.u64);
io.mapRequired("u32", bt.u32);
io.mapRequired("u16", bt.u16);
@@ -191,6 +200,7 @@ TEST(YAMLIO, TestReadBuiltInTypes) {
BuiltInTypes map;
Input yin("---\n"
"str: hello there\n"
+ "stdstr: hello where?\n"
"u64: 5000000000\n"
"u32: 4000000000\n"
"u16: 65000\n"
@@ -211,6 +221,7 @@ TEST(YAMLIO, TestReadBuiltInTypes) {
EXPECT_FALSE(yin.error());
EXPECT_TRUE(map.str.equals("hello there"));
+ EXPECT_TRUE(map.stdstr == "hello where?");
EXPECT_EQ(map.u64, 5000000000ULL);
EXPECT_EQ(map.u32, 4000000000U);
EXPECT_EQ(map.u16, 65000);
@@ -237,6 +248,7 @@ TEST(YAMLIO, TestReadWriteBuiltInTypes) {
{
BuiltInTypes map;
map.str = "one two";
+ map.stdstr = "three four";
map.u64 = 6000000000ULL;
map.u32 = 3000000000U;
map.u16 = 50000;
@@ -265,6 +277,7 @@ TEST(YAMLIO, TestReadWriteBuiltInTypes) {
EXPECT_FALSE(yin.error());
EXPECT_TRUE(map.str.equals("one two"));
+ EXPECT_TRUE(map.stdstr == "three four");
EXPECT_EQ(map.u64, 6000000000ULL);
EXPECT_EQ(map.u32, 3000000000U);
EXPECT_EQ(map.u16, 50000);
@@ -289,6 +302,23 @@ struct StringTypes {
llvm::StringRef str3;
llvm::StringRef str4;
llvm::StringRef str5;
+ llvm::StringRef str6;
+ llvm::StringRef str7;
+ llvm::StringRef str8;
+ llvm::StringRef str9;
+ llvm::StringRef str10;
+ llvm::StringRef str11;
+ std::string stdstr1;
+ std::string stdstr2;
+ std::string stdstr3;
+ std::string stdstr4;
+ std::string stdstr5;
+ std::string stdstr6;
+ std::string stdstr7;
+ std::string stdstr8;
+ std::string stdstr9;
+ std::string stdstr10;
+ std::string stdstr11;
};
namespace llvm {
@@ -301,6 +331,23 @@ namespace yaml {
io.mapRequired("str3", st.str3);
io.mapRequired("str4", st.str4);
io.mapRequired("str5", st.str5);
+ io.mapRequired("str6", st.str6);
+ io.mapRequired("str7", st.str7);
+ io.mapRequired("str8", st.str8);
+ io.mapRequired("str9", st.str9);
+ io.mapRequired("str10", st.str10);
+ io.mapRequired("str11", st.str11);
+ io.mapRequired("stdstr1", st.stdstr1);
+ io.mapRequired("stdstr2", st.stdstr2);
+ io.mapRequired("stdstr3", st.stdstr3);
+ io.mapRequired("stdstr4", st.stdstr4);
+ io.mapRequired("stdstr5", st.stdstr5);
+ io.mapRequired("stdstr6", st.stdstr6);
+ io.mapRequired("stdstr7", st.stdstr7);
+ io.mapRequired("stdstr8", st.stdstr8);
+ io.mapRequired("stdstr9", st.stdstr9);
+ io.mapRequired("stdstr10", st.stdstr10);
+ io.mapRequired("stdstr11", st.stdstr11);
}
};
}
@@ -315,6 +362,23 @@ TEST(YAMLIO, TestReadWriteStringTypes) {
map.str3 = "`ccc";
map.str4 = "@ddd";
map.str5 = "";
+ map.str6 = "0000000004000000";
+ map.str7 = "true";
+ map.str8 = "FALSE";
+ map.str9 = "~";
+ map.str10 = "0.2e20";
+ map.str11 = "0x30";
+ map.stdstr1 = "'eee";
+ map.stdstr2 = "\"fff";
+ map.stdstr3 = "`ggg";
+ map.stdstr4 = "@hhh";
+ map.stdstr5 = "";
+ map.stdstr6 = "0000000004000000";
+ map.stdstr7 = "true";
+ map.stdstr8 = "FALSE";
+ map.stdstr9 = "~";
+ map.stdstr10 = "0.2e20";
+ map.stdstr11 = "0x30";
llvm::raw_string_ostream ostr(intermediate);
Output yout(ostr);
@@ -327,6 +391,18 @@ TEST(YAMLIO, TestReadWriteStringTypes) {
EXPECT_NE(llvm::StringRef::npos, flowOut.find("'`ccc'"));
EXPECT_NE(llvm::StringRef::npos, flowOut.find("'@ddd'"));
EXPECT_NE(llvm::StringRef::npos, flowOut.find("''\n"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0000000004000000'\n"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("'true'\n"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("'FALSE'\n"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("'~'\n"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0.2e20'\n"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0x30'\n"));
+ EXPECT_NE(std::string::npos, flowOut.find("'''eee"));
+ EXPECT_NE(std::string::npos, flowOut.find("'\"fff'"));
+ EXPECT_NE(std::string::npos, flowOut.find("'`ggg'"));
+ EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
+ EXPECT_NE(std::string::npos, flowOut.find("''\n"));
+ EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
{
Input yin(intermediate);
@@ -339,6 +415,13 @@ TEST(YAMLIO, TestReadWriteStringTypes) {
EXPECT_TRUE(map.str3.equals("`ccc"));
EXPECT_TRUE(map.str4.equals("@ddd"));
EXPECT_TRUE(map.str5.equals(""));
+ EXPECT_TRUE(map.str6.equals("0000000004000000"));
+ EXPECT_TRUE(map.stdstr1 == "'eee");
+ EXPECT_TRUE(map.stdstr2 == "\"fff");
+ EXPECT_TRUE(map.stdstr3 == "`ggg");
+ EXPECT_TRUE(map.stdstr4 == "@hhh");
+ EXPECT_TRUE(map.stdstr5 == "");
+ EXPECT_TRUE(map.stdstr6 == "0000000004000000");
}
}
@@ -564,6 +647,7 @@ namespace yaml {
return "malformed by";
}
}
+ static bool mustQuote(StringRef) { return true; }
};
}
}
@@ -625,6 +709,8 @@ namespace yaml {
value = n;
return StringRef();
}
+
+ static bool mustQuote(StringRef) { return false; }
};
}
}
@@ -1085,86 +1171,49 @@ TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {
//===----------------------------------------------------------------------===//
-// Test dyn_cast<> on IO object
+// Test mapping validation
//===----------------------------------------------------------------------===//
-struct DynCast {
- int value;
+struct MyValidation {
+ double value;
};
-typedef std::vector<DynCast> DynCastSequence;
-LLVM_YAML_IS_SEQUENCE_VECTOR(DynCast)
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyValidation)
namespace llvm {
namespace yaml {
template <>
- struct MappingTraits<DynCast> {
- static void mapping(IO &io, DynCast& info) {
- // Change 10 to 13 when writing yaml.
- if (Output *output = dyn_cast<Output>(&io)) {
- (void)output;
- if (info.value == 10)
- info.value = 13;
- }
- io.mapRequired("value", info.value);
- // Change 20 to 23 when parsing yaml.
- if (Input *input = dyn_cast<Input>(&io)) {
- (void)input;
- if (info.value == 20)
- info.value = 23;
- }
+ struct MappingTraits<MyValidation> {
+ static void mapping(IO &io, MyValidation &d) {
+ io.mapRequired("value", d.value);
+ }
+ static StringRef validate(IO &io, MyValidation &d) {
+ if (d.value < 0)
+ return "negative value";
+ return StringRef();
}
};
+ }
}
-}
+
//
-// Test writing then reading back a sequence of mappings
+// Test that validate() is called and complains about the negative value.
//
-TEST(YAMLIO, TestDynCast) {
- std::string intermediate;
- {
- DynCast entry1;
- entry1.value = 10;
- DynCast entry2;
- entry2.value = 20;
- DynCast entry3;
- entry3.value = 30;
- DynCastSequence seq;
- seq.push_back(entry1);
- seq.push_back(entry2);
- seq.push_back(entry3);
-
- llvm::raw_string_ostream ostr(intermediate);
- Output yout(ostr);
- yout << seq;
- }
-
- {
- Input yin(intermediate);
- DynCastSequence seq2;
- yin >> seq2;
-
- EXPECT_FALSE(yin.error());
- EXPECT_EQ(seq2.size(), 3UL);
- EXPECT_EQ(seq2[0].value, 13); // Verify changed to 13.
- EXPECT_EQ(seq2[1].value, 23); // Verify changed to 23.
- EXPECT_EQ(seq2[2].value, 30); // Verify stays same.
- }
+TEST(YAMLIO, TestValidatingInput) {
+ std::vector<MyValidation> docList;
+ Input yin("--- \nvalue: 3.0\n"
+ "--- \nvalue: -1.0\n...\n",
+ nullptr, suppressErrorMessages);
+ yin >> docList;
+ EXPECT_TRUE(!!yin.error());
}
-
//===----------------------------------------------------------------------===//
// Test error handling
//===----------------------------------------------------------------------===//
-
-
-static void suppressErrorMessages(const llvm::SMDiagnostic &, void *) {
-}
-
-
//
// Test error handling of unknown enumerated scalar
//
@@ -1175,10 +1224,10 @@ TEST(YAMLIO, TestColorsReadError) {
"c2: purple\n"
"c3: green\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> map;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1192,11 +1241,11 @@ TEST(YAMLIO, TestFlagsReadError) {
"f2: [ round, hollow ]\n"
"f3: []\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> map;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1211,11 +1260,11 @@ TEST(YAMLIO, TestReadBuiltInTypesUint8Error) {
"- 0\n"
"- 257\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1230,11 +1279,11 @@ TEST(YAMLIO, TestReadBuiltInTypesUint16Error) {
"- 0\n"
"- 66000\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1249,11 +1298,11 @@ TEST(YAMLIO, TestReadBuiltInTypesUint32Error) {
"- 0\n"
"- 5000000000\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1268,11 +1317,11 @@ TEST(YAMLIO, TestReadBuiltInTypesUint64Error) {
"- 0\n"
"- 19446744073709551615\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1288,11 +1337,11 @@ TEST(YAMLIO, TestReadBuiltInTypesint8OverError) {
"- 127\n"
"- 128\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
//
@@ -1306,11 +1355,11 @@ TEST(YAMLIO, TestReadBuiltInTypesint8UnderError) {
"- 127\n"
"- -129\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1326,11 +1375,11 @@ TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) {
"- -32768\n"
"- -32769\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1345,11 +1394,11 @@ TEST(YAMLIO, TestReadBuiltInTypesint16OverError) {
"- -32768\n"
"- 32768\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1365,11 +1414,11 @@ TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) {
"- -2147483648\n"
"- -2147483649\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
//
@@ -1383,11 +1432,11 @@ TEST(YAMLIO, TestReadBuiltInTypesint32OverError) {
"- -2147483648\n"
"- 2147483649\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1403,11 +1452,11 @@ TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) {
"- 9223372036854775807\n"
"- -9223372036854775809\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
//
@@ -1421,11 +1470,11 @@ TEST(YAMLIO, TestReadBuiltInTypesint64OverError) {
"- 9223372036854775807\n"
"- 9223372036854775809\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
//
@@ -1440,11 +1489,11 @@ TEST(YAMLIO, TestReadBuiltInTypesFloatError) {
"- -123.456\n"
"- 1.2.3\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
//
@@ -1459,11 +1508,11 @@ TEST(YAMLIO, TestReadBuiltInTypesDoubleError) {
"- -123.456\n"
"- 1.2.3\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
//
@@ -1477,11 +1526,11 @@ TEST(YAMLIO, TestReadBuiltInTypesHex8Error) {
"- 0xFE\n"
"- 0x123\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
@@ -1496,11 +1545,11 @@ TEST(YAMLIO, TestReadBuiltInTypesHex16Error) {
"- 0xFEFF\n"
"- 0x12345\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
//
@@ -1514,11 +1563,11 @@ TEST(YAMLIO, TestReadBuiltInTypesHex32Error) {
"- 0xFEFF0000\n"
"- 0x1234556789\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
//
@@ -1532,11 +1581,11 @@ TEST(YAMLIO, TestReadBuiltInTypesHex64Error) {
"- 0xFFEEDDCCBBAA9988\n"
"- 0x12345567890ABCDEF0\n"
"...\n",
- /*Ctxt=*/NULL,
+ /*Ctxt=*/nullptr,
suppressErrorMessages);
yin >> seq;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
TEST(YAMLIO, TestMalformedMapFailsGracefully) {
@@ -1544,15 +1593,15 @@ TEST(YAMLIO, TestMalformedMapFailsGracefully) {
{
// We pass the suppressErrorMessages handler to handle the error
// message generated in the constructor of Input.
- Input yin("{foo:3, bar: 5}", /*Ctxt=*/NULL, suppressErrorMessages);
+ Input yin("{foo:3, bar: 5}", /*Ctxt=*/nullptr, suppressErrorMessages);
yin >> doc;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
{
- Input yin("---\nfoo:3\nbar: 5\n...\n", /*Ctxt=*/NULL, suppressErrorMessages);
+ Input yin("---\nfoo:3\nbar: 5\n...\n", /*Ctxt=*/nullptr, suppressErrorMessages);
yin >> doc;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
}
@@ -1624,7 +1673,7 @@ TEST(YAMLIO, TestEmptyStringFailsForMapWithRequiredFields) {
FooBar doc;
Input yin("");
yin >> doc;
- EXPECT_TRUE(yin.error());
+ EXPECT_TRUE(!!yin.error());
}
TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) {
@@ -1636,7 +1685,7 @@ TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) {
TEST(YAMLIO, TestEmptyStringSucceedsForSequence) {
std::vector<uint8_t> seq;
- Input yin("", /*Ctxt=*/NULL, suppressErrorMessages);
+ Input yin("", /*Ctxt=*/nullptr, suppressErrorMessages);
yin >> seq;
EXPECT_FALSE(yin.error());
diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp
index 2b797b43666b..44d27d041021 100644
--- a/unittests/Support/raw_ostream_test.cpp
+++ b/unittests/Support/raw_ostream_test.cpp
@@ -69,7 +69,7 @@ TEST(raw_ostreamTest, Types_Buffered) {
EXPECT_EQ("1.100000e+00", printToString(1.1));
// void*
- EXPECT_EQ("0x0", printToString((void*) 0));
+ EXPECT_EQ("0x0", printToString((void*) nullptr));
EXPECT_EQ("0xbeef", printToString((void*) 0xbeef));
EXPECT_EQ("0xdeadbeef", printToString((void*) 0xdeadbeef));
@@ -100,7 +100,7 @@ TEST(raw_ostreamTest, Types_Unbuffered) {
EXPECT_EQ("1.100000e+00", printToStringUnbuffered(1.1));
// void*
- EXPECT_EQ("0x0", printToStringUnbuffered((void*) 0));
+ EXPECT_EQ("0x0", printToStringUnbuffered((void*) nullptr));
EXPECT_EQ("0xbeef", printToStringUnbuffered((void*) 0xbeef));
EXPECT_EQ("0xdeadbeef", printToStringUnbuffered((void*) 0xdeadbeef));
diff --git a/unittests/Transforms/DebugIR/CMakeLists.txt b/unittests/Transforms/DebugIR/CMakeLists.txt
index 4b471939ef1f..88734d2b8fcf 100644
--- a/unittests/Transforms/DebugIR/CMakeLists.txt
+++ b/unittests/Transforms/DebugIR/CMakeLists.txt
@@ -1,5 +1,7 @@
set(LLVM_LINK_COMPONENTS
+ Core
Instrumentation
+ Support
)
add_llvm_unittest(DebugIRTests
diff --git a/unittests/Transforms/DebugIR/DebugIR.cpp b/unittests/Transforms/DebugIR/DebugIR.cpp
index 7d213fd0567a..41df14721684 100644
--- a/unittests/Transforms/DebugIR/DebugIR.cpp
+++ b/unittests/Transforms/DebugIR/DebugIR.cpp
@@ -13,17 +13,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Triple.h"
+#include "../lib/Transforms/Instrumentation/DebugIR.h"
#include "llvm/Config/config.h"
-#include "llvm/DebugInfo.h"
-#include "llvm/DIBuilder.h"
+#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/Host.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/Transforms/Instrumentation.h"
-#include "../lib/Transforms/Instrumentation/DebugIR.h"
-
// These tests do not depend on MCJIT, but we use the TrivialModuleBuilder
// helper class to construct some trivial Modules.
#include "../unittests/ExecutionEngine/MCJIT/MCJITTestBase.h"
@@ -56,16 +56,17 @@ void insertCUDescriptor(Module *M, StringRef File, StringRef Dir,
/// Attempts to remove file at Path and returns true if it existed, or false if
/// it did not.
bool removeIfExists(StringRef Path) {
- bool existed = false;
- sys::fs::remove(Path, existed);
- return existed;
+ // This is an approximation, on error we don't know in general if the file
+ // existed or not.
+ std::error_code EC = sys::fs::remove(Path, false);
+ return EC != llvm::errc::no_such_file_or_directory;
}
char * current_dir() {
#if defined(LLVM_ON_WIN32) || defined(HAVE_GETCWD)
// calling getcwd (or _getcwd() on windows) with a null buffer makes it
// allocate a sufficiently sized buffer to store the current working dir.
- return getcwd_impl(0, 0);
+ return getcwd_impl(nullptr, 0);
#else
return 0;
#endif
@@ -90,8 +91,8 @@ protected:
LLVMContext Context;
char *cwd;
- OwningPtr<Module> M;
- OwningPtr<DebugIR> D;
+ std::unique_ptr<Module> M;
+ std::unique_ptr<DebugIR> D;
};
// Test empty named Module that is not supposed to be output to disk.
@@ -278,7 +279,7 @@ TEST_F(TestDebugIR, ExistingMetadataRetained) {
// verify DebugIR did not generate a file
ASSERT_FALSE(removeIfExists(Path)) << "Unexpected file " << Path;
- DICompileUnit CU(*Finder.compile_unit_begin());
+ DICompileUnit CU(*Finder.compile_units().begin());
// Verify original CU information is retained
ASSERT_EQ(Filename, CU.getFilename());
diff --git a/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp b/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
new file mode 100644
index 000000000000..0d3a239da347
--- /dev/null
+++ b/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
@@ -0,0 +1,102 @@
+//===- ASanStackFrameLayoutTest.cpp - Tests for ComputeASanStackFrameLayout===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "gtest/gtest.h"
+#include <sstream>
+
+using namespace llvm;
+
+static std::string
+ShadowBytesToString(ArrayRef<uint8_t> ShadowBytes) {
+ std::ostringstream os;
+ for (size_t i = 0, n = ShadowBytes.size(); i < n; i++) {
+ switch (ShadowBytes[i]) {
+ case kAsanStackLeftRedzoneMagic: os << "L"; break;
+ case kAsanStackRightRedzoneMagic: os << "R"; break;
+ case kAsanStackMidRedzoneMagic: os << "M"; break;
+ default: os << (unsigned)ShadowBytes[i];
+ }
+ }
+ return os.str();
+}
+
+static void TestLayout(SmallVector<ASanStackVariableDescription, 10> Vars,
+ size_t Granularity, size_t MinHeaderSize,
+ const std::string &ExpectedDescr,
+ const std::string &ExpectedShadow) {
+ ASanStackFrameLayout L;
+ ComputeASanStackFrameLayout(Vars, Granularity, MinHeaderSize, &L);
+ EXPECT_EQ(ExpectedDescr, L.DescriptionString);
+ EXPECT_EQ(ExpectedShadow, ShadowBytesToString(L.ShadowBytes));
+}
+
+TEST(ASanStackFrameLayout, Test) {
+#define VEC1(a) SmallVector<ASanStackVariableDescription, 10>(1, a)
+#define VEC(a) \
+ SmallVector<ASanStackVariableDescription, 10>(a, a + sizeof(a) / sizeof(a[0]))
+
+#define VAR(name, size, alignment) \
+ ASanStackVariableDescription name##size##_##alignment = { \
+ #name #size "_" #alignment, \
+ size, \
+ alignment, \
+ 0, \
+ 0 \
+ }
+
+ VAR(a, 1, 1);
+ VAR(p, 1, 32);
+ VAR(p, 1, 256);
+ VAR(a, 2, 1);
+ VAR(a, 3, 1);
+ VAR(a, 4, 1);
+ VAR(a, 7, 1);
+ VAR(a, 8, 1);
+ VAR(a, 9, 1);
+ VAR(a, 16, 1);
+ VAR(a, 41, 1);
+ VAR(a, 105, 1);
+
+ TestLayout(VEC1(a1_1), 8, 16, "1 16 1 4 a1_1", "LL1R");
+ TestLayout(VEC1(a1_1), 64, 64, "1 64 1 4 a1_1", "L1");
+ TestLayout(VEC1(p1_32), 8, 32, "1 32 1 5 p1_32", "LLLL1RRR");
+ TestLayout(VEC1(p1_32), 8, 64, "1 64 1 5 p1_32", "LLLLLLLL1RRRRRRR");
+
+ TestLayout(VEC1(a1_1), 8, 32, "1 32 1 4 a1_1", "LLLL1RRR");
+ TestLayout(VEC1(a2_1), 8, 32, "1 32 2 4 a2_1", "LLLL2RRR");
+ TestLayout(VEC1(a3_1), 8, 32, "1 32 3 4 a3_1", "LLLL3RRR");
+ TestLayout(VEC1(a4_1), 8, 32, "1 32 4 4 a4_1", "LLLL4RRR");
+ TestLayout(VEC1(a7_1), 8, 32, "1 32 7 4 a7_1", "LLLL7RRR");
+ TestLayout(VEC1(a8_1), 8, 32, "1 32 8 4 a8_1", "LLLL0RRR");
+ TestLayout(VEC1(a9_1), 8, 32, "1 32 9 4 a9_1", "LLLL01RR");
+ TestLayout(VEC1(a16_1), 8, 32, "1 32 16 5 a16_1", "LLLL00RR");
+ TestLayout(VEC1(p1_256), 8, 32, "1 256 1 6 p1_256",
+ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL1RRR");
+ TestLayout(VEC1(a41_1), 8, 32, "1 32 41 5 a41_1", "LLLL000001RRRRRR");
+ TestLayout(VEC1(a105_1), 8, 32, "1 32 105 6 a105_1",
+ "LLLL00000000000001RRRRRR");
+
+ {
+ ASanStackVariableDescription t[] = {a1_1, p1_256};
+ TestLayout(VEC(t), 8, 32,
+ "2 256 1 6 p1_256 272 1 4 a1_1",
+ "LLLLLLLL" "LLLLLLLL" "LLLLLLLL" "LLLLLLLL" "1M1R");
+ }
+
+ {
+ ASanStackVariableDescription t[] = {a1_1, a16_1, a41_1};
+ TestLayout(VEC(t), 8, 32,
+ "3 32 1 4 a1_1 48 16 5 a16_1 80 41 5 a41_1",
+ "LLLL" "1M00" "MM00" "0001" "RRRR");
+ }
+#undef VEC1
+#undef VEC
+#undef VAR
+}
diff --git a/unittests/Transforms/Utils/CMakeLists.txt b/unittests/Transforms/Utils/CMakeLists.txt
index 0656390cbbea..ffa1d49d380b 100644
--- a/unittests/Transforms/Utils/CMakeLists.txt
+++ b/unittests/Transforms/Utils/CMakeLists.txt
@@ -1,10 +1,12 @@
set(LLVM_LINK_COMPONENTS
+ Core
+ Support
TransformUtils
)
add_llvm_unittest(UtilsTests
+ ASanStackFrameLayoutTest.cpp
Cloning.cpp
IntegerDivision.cpp
Local.cpp
- SpecialCaseList.cpp
)
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index e19ae5bc2fb4..b3a1f5b10521 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -7,15 +7,22 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Constant.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/Transforms/Utils/Cloning.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -25,7 +32,7 @@ namespace {
class CloneInstruction : public ::testing::Test {
protected:
virtual void SetUp() {
- V = NULL;
+ V = nullptr;
}
template <typename T>
@@ -173,4 +180,230 @@ TEST_F(CloneInstruction, Attributes) {
delete F2;
}
+TEST_F(CloneInstruction, CallingConvention) {
+ Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
+ FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
+
+ Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
+ F1->setCallingConv(CallingConv::Cold);
+ BasicBlock *BB = BasicBlock::Create(context, "", F1);
+ IRBuilder<> Builder(BB);
+ Builder.CreateRetVoid();
+
+ Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
+
+ SmallVector<ReturnInst*, 4> Returns;
+ ValueToValueMapTy VMap;
+ VMap[F1->arg_begin()] = F2->arg_begin();
+
+ CloneFunctionInto(F2, F1, VMap, false, Returns);
+ EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
+
+ delete F1;
+ delete F2;
+}
+
+class CloneFunc : public ::testing::Test {
+protected:
+ virtual void SetUp() {
+ SetupModule();
+ CreateOldFunc();
+ CreateNewFunc();
+ SetupFinder();
+ }
+
+ virtual void TearDown() {
+ delete Finder;
+ }
+
+ void SetupModule() {
+ M = new Module("", C);
+ }
+
+ void CreateOldFunc() {
+ FunctionType* FuncType = FunctionType::get(Type::getVoidTy(C), false);
+ OldFunc = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", M);
+ CreateOldFunctionBodyAndDI();
+ }
+
+ void CreateOldFunctionBodyAndDI() {
+ DIBuilder DBuilder(*M);
+ IRBuilder<> IBuilder(C);
+
+ // Function DI
+ DIFile File = DBuilder.createFile("filename.c", "/file/dir/");
+ DIArray ParamTypes = DBuilder.getOrCreateArray(ArrayRef<Value*>());
+ DICompositeType FuncType = DBuilder.createSubroutineType(File, ParamTypes);
+ DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
+ "filename.c", "/file/dir", "CloneFunc", false, "", 0);
+
+ DISubprogram Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4,
+ FuncType, true, true, 3, 0, false, OldFunc);
+
+ // Function body
+ BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
+ IBuilder.SetInsertPoint(Entry);
+ DebugLoc Loc = DebugLoc::get(3, 2, Subprogram);
+ IBuilder.SetCurrentDebugLocation(Loc);
+ AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C));
+ IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram));
+ Value* AllocaContent = IBuilder.getInt32(1);
+ Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
+ IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
+ Instruction* Terminator = IBuilder.CreateRetVoid();
+
+ // Create a local variable around the alloca
+ DIType IntType = DBuilder.createBasicType("int", 32, 0,
+ dwarf::DW_ATE_signed);
+ DIVariable Variable = DBuilder.createLocalVariable(
+ dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
+ DBuilder.insertDeclare(Alloca, Variable, Store);
+ DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, Terminator);
+ // Finalize the debug info
+ DBuilder.finalize();
+
+
+ // Create another, empty, compile unit
+ DIBuilder DBuilder2(*M);
+ DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
+ "extra.c", "/file/dir", "CloneFunc", false, "", 0);
+ DBuilder2.finalize();
+ }
+
+ void CreateNewFunc() {
+ ValueToValueMapTy VMap;
+ NewFunc = CloneFunction(OldFunc, VMap, true, nullptr);
+ M->getFunctionList().push_back(NewFunc);
+ }
+
+ void SetupFinder() {
+ Finder = new DebugInfoFinder();
+ Finder->processModule(*M);
+ }
+
+ LLVMContext C;
+ Function* OldFunc;
+ Function* NewFunc;
+ Module* M;
+ DebugInfoFinder* Finder;
+};
+
+// Test that a new, distinct function was created.
+TEST_F(CloneFunc, NewFunctionCreated) {
+ EXPECT_NE(OldFunc, NewFunc);
+}
+
+// Test that a new subprogram entry was added and is pointing to the new
+// function, while the original subprogram still points to the old one.
+TEST_F(CloneFunc, Subprogram) {
+ unsigned SubprogramCount = Finder->subprogram_count();
+ EXPECT_EQ(2U, SubprogramCount);
+
+ auto Iter = Finder->subprograms().begin();
+ DISubprogram Sub1(*Iter);
+ EXPECT_TRUE(Sub1.Verify());
+ Iter++;
+ DISubprogram Sub2(*Iter);
+ EXPECT_TRUE(Sub2.Verify());
+
+ EXPECT_TRUE((Sub1.getFunction() == OldFunc && Sub2.getFunction() == NewFunc)
+ || (Sub1.getFunction() == NewFunc && Sub2.getFunction() == OldFunc));
+}
+
+// Test that the new subprogram entry was not added to the CU which doesn't
+// contain the old subprogram entry.
+TEST_F(CloneFunc, SubprogramInRightCU) {
+ EXPECT_EQ(2U, Finder->compile_unit_count());
+
+ auto Iter = Finder->compile_units().begin();
+ DICompileUnit CU1(*Iter);
+ EXPECT_TRUE(CU1.Verify());
+ Iter++;
+ DICompileUnit CU2(*Iter);
+ EXPECT_TRUE(CU2.Verify());
+ EXPECT_TRUE(CU1.getSubprograms().getNumElements() == 0
+ || CU2.getSubprograms().getNumElements() == 0);
+}
+
+// Test that instructions in the old function still belong to it in the
+// metadata, while instruction in the new function belong to the new one.
+TEST_F(CloneFunc, InstructionOwnership) {
+ inst_iterator OldIter = inst_begin(OldFunc);
+ inst_iterator OldEnd = inst_end(OldFunc);
+ inst_iterator NewIter = inst_begin(NewFunc);
+ inst_iterator NewEnd = inst_end(NewFunc);
+ while (OldIter != OldEnd && NewIter != NewEnd) {
+ Instruction& OldI = *OldIter;
+ Instruction& NewI = *NewIter;
+ EXPECT_NE(&OldI, &NewI);
+
+ EXPECT_EQ(OldI.hasMetadata(), NewI.hasMetadata());
+ if (OldI.hasMetadata()) {
+ const DebugLoc& OldDL = OldI.getDebugLoc();
+ const DebugLoc& NewDL = NewI.getDebugLoc();
+
+ // Verify that the debug location data is the same
+ EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
+ EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
+
+ // But that they belong to different functions
+ DISubprogram OldSubprogram(OldDL.getScope(C));
+ DISubprogram NewSubprogram(NewDL.getScope(C));
+ EXPECT_TRUE(OldSubprogram.Verify());
+ EXPECT_TRUE(NewSubprogram.Verify());
+ EXPECT_EQ(OldFunc, OldSubprogram.getFunction());
+ EXPECT_EQ(NewFunc, NewSubprogram.getFunction());
+ }
+
+ ++OldIter;
+ ++NewIter;
+ }
+ EXPECT_EQ(OldEnd, OldIter);
+ EXPECT_EQ(NewEnd, NewIter);
+}
+
+// Test that the arguments for debug intrinsics in the new function were
+// properly cloned
+TEST_F(CloneFunc, DebugIntrinsics) {
+ inst_iterator OldIter = inst_begin(OldFunc);
+ inst_iterator OldEnd = inst_end(OldFunc);
+ inst_iterator NewIter = inst_begin(NewFunc);
+ inst_iterator NewEnd = inst_end(NewFunc);
+ while (OldIter != OldEnd && NewIter != NewEnd) {
+ Instruction& OldI = *OldIter;
+ Instruction& NewI = *NewIter;
+ if (DbgDeclareInst* OldIntrin = dyn_cast<DbgDeclareInst>(&OldI)) {
+ DbgDeclareInst* NewIntrin = dyn_cast<DbgDeclareInst>(&NewI);
+ EXPECT_TRUE(NewIntrin);
+
+ // Old address must belong to the old function
+ EXPECT_EQ(OldFunc, cast<AllocaInst>(OldIntrin->getAddress())->
+ getParent()->getParent());
+ // New address must belong to the new function
+ EXPECT_EQ(NewFunc, cast<AllocaInst>(NewIntrin->getAddress())->
+ getParent()->getParent());
+
+ // Old variable must belong to the old function
+ EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
+ .getContext()).getFunction());
+ // New variable must belong to the New function
+ EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
+ .getContext()).getFunction());
+ } else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
+ DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
+ EXPECT_TRUE(NewIntrin);
+
+ // Old variable must belong to the old function
+ EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
+ .getContext()).getFunction());
+ // New variable must belong to the New function
+ EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
+ .getContext()).getFunction());
+ }
+
+ ++OldIter;
+ ++NewIter;
+ }
+}
+
}
diff --git a/unittests/Transforms/Utils/IntegerDivision.cpp b/unittests/Transforms/Utils/IntegerDivision.cpp
index 44c2328ee354..f7318a2e7897 100644
--- a/unittests/Transforms/Utils/IntegerDivision.cpp
+++ b/unittests/Transforms/Utils/IntegerDivision.cpp
@@ -19,6 +19,7 @@ using namespace llvm;
namespace {
+
TEST(IntegerDivision, SDiv) {
LLVMContext &C(getGlobalContext());
Module M("test division", C);
@@ -139,4 +140,125 @@ TEST(IntegerDivision, URem) {
EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
}
+
+TEST(IntegerDivision, SDiv64) {
+ LLVMContext &C(getGlobalContext());
+ Module M("test division", C);
+ IRBuilder<> Builder(C);
+
+ SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
+ Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
+ ArgTys, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+ assert(F->getArgumentList().size() == 2);
+
+ BasicBlock *BB = BasicBlock::Create(C, "", F);
+ Builder.SetInsertPoint(BB);
+
+ Function::arg_iterator AI = F->arg_begin();
+ Value *A = AI++;
+ Value *B = AI++;
+
+ Value *Div = Builder.CreateSDiv(A, B);
+ EXPECT_TRUE(BB->front().getOpcode() == Instruction::SDiv);
+
+ Value *Ret = Builder.CreateRet(Div);
+
+ expandDivision(cast<BinaryOperator>(Div));
+ EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
+
+ Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
+ EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::Sub);
+}
+
+TEST(IntegerDivision, UDiv64) {
+ LLVMContext &C(getGlobalContext());
+ Module M("test division", C);
+ IRBuilder<> Builder(C);
+
+ SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
+ Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
+ ArgTys, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+ assert(F->getArgumentList().size() == 2);
+
+ BasicBlock *BB = BasicBlock::Create(C, "", F);
+ Builder.SetInsertPoint(BB);
+
+ Function::arg_iterator AI = F->arg_begin();
+ Value *A = AI++;
+ Value *B = AI++;
+
+ Value *Div = Builder.CreateUDiv(A, B);
+ EXPECT_TRUE(BB->front().getOpcode() == Instruction::UDiv);
+
+ Value *Ret = Builder.CreateRet(Div);
+
+ expandDivision(cast<BinaryOperator>(Div));
+ EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
+
+ Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
+ EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::PHI);
+}
+
+TEST(IntegerDivision, SRem64) {
+ LLVMContext &C(getGlobalContext());
+ Module M("test remainder", C);
+ IRBuilder<> Builder(C);
+
+ SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
+ Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
+ ArgTys, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+ assert(F->getArgumentList().size() == 2);
+
+ BasicBlock *BB = BasicBlock::Create(C, "", F);
+ Builder.SetInsertPoint(BB);
+
+ Function::arg_iterator AI = F->arg_begin();
+ Value *A = AI++;
+ Value *B = AI++;
+
+ Value *Rem = Builder.CreateSRem(A, B);
+ EXPECT_TRUE(BB->front().getOpcode() == Instruction::SRem);
+
+ Value *Ret = Builder.CreateRet(Rem);
+
+ expandRemainder(cast<BinaryOperator>(Rem));
+ EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);
+
+ Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
+ EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
+}
+
+TEST(IntegerDivision, URem64) {
+ LLVMContext &C(getGlobalContext());
+ Module M("test remainder", C);
+ IRBuilder<> Builder(C);
+
+ SmallVector<Type*, 2> ArgTys(2, Builder.getInt64Ty());
+ Function *F = Function::Create(FunctionType::get(Builder.getInt64Ty(),
+ ArgTys, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+ assert(F->getArgumentList().size() == 2);
+
+ BasicBlock *BB = BasicBlock::Create(C, "", F);
+ Builder.SetInsertPoint(BB);
+
+ Function::arg_iterator AI = F->arg_begin();
+ Value *A = AI++;
+ Value *B = AI++;
+
+ Value *Rem = Builder.CreateURem(A, B);
+ EXPECT_TRUE(BB->front().getOpcode() == Instruction::URem);
+
+ Value *Ret = Builder.CreateRet(Rem);
+
+ expandRemainder(cast<BinaryOperator>(Rem));
+ EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);
+
+ Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
+ EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
+}
+
}
diff --git a/unittests/Transforms/Utils/SpecialCaseList.cpp b/unittests/Transforms/Utils/SpecialCaseList.cpp
deleted file mode 100644
index 07ac908caabc..000000000000
--- a/unittests/Transforms/Utils/SpecialCaseList.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-//===- SpecialCaseList.cpp - Unit tests for SpecialCaseList ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/Function.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Transforms/Utils/SpecialCaseList.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-namespace {
-
-class SpecialCaseListTest : public ::testing::Test {
-protected:
- Function *makeFunction(StringRef Name, Module &M) {
- return Function::Create(FunctionType::get(Type::getVoidTy(Ctx), false),
- GlobalValue::ExternalLinkage,
- Name,
- &M);
- }
-
- GlobalVariable *makeGlobal(StringRef Name, StringRef StructName, Module &M) {
- StructType *ST =
- StructType::create(StructName, Type::getInt32Ty(Ctx), (Type*)0);
- return new GlobalVariable(
- M, ST, false, GlobalValue::ExternalLinkage, 0, Name);
- }
-
- GlobalAlias *makeAlias(StringRef Name, GlobalValue *Aliasee) {
- return new GlobalAlias(Aliasee->getType(), GlobalValue::ExternalLinkage,
- Name, Aliasee, Aliasee->getParent());
- }
-
- SpecialCaseList *makeSpecialCaseList(StringRef List, std::string &Error) {
- OwningPtr<MemoryBuffer> MB(MemoryBuffer::getMemBuffer(List));
- return SpecialCaseList::create(MB.get(), Error);
- }
-
- SpecialCaseList *makeSpecialCaseList(StringRef List) {
- std::string Error;
- SpecialCaseList *SCL = makeSpecialCaseList(List, Error);
- assert(SCL);
- assert(Error == "");
- return SCL;
- }
-
- LLVMContext Ctx;
-};
-
-TEST_F(SpecialCaseListTest, ModuleIsIn) {
- Module M("hello", Ctx);
- Function *F = makeFunction("foo", M);
- GlobalVariable *GV = makeGlobal("bar", "t", M);
-
- OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("# This is a comment.\n"
- "\n"
- "src:hello\n"));
- EXPECT_TRUE(SCL->isIn(M));
- EXPECT_TRUE(SCL->isIn(*F));
- EXPECT_TRUE(SCL->isIn(*GV));
-
- SCL.reset(makeSpecialCaseList("src:he*o\n"));
- EXPECT_TRUE(SCL->isIn(M));
- EXPECT_TRUE(SCL->isIn(*F));
- EXPECT_TRUE(SCL->isIn(*GV));
-
- SCL.reset(makeSpecialCaseList("src:hi\n"));
- EXPECT_FALSE(SCL->isIn(M));
- EXPECT_FALSE(SCL->isIn(*F));
- EXPECT_FALSE(SCL->isIn(*GV));
-}
-
-TEST_F(SpecialCaseListTest, FunctionIsIn) {
- Module M("hello", Ctx);
- Function *Foo = makeFunction("foo", M);
- Function *Bar = makeFunction("bar", M);
-
- OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("fun:foo\n"));
- EXPECT_TRUE(SCL->isIn(*Foo));
- EXPECT_FALSE(SCL->isIn(*Bar));
-
- SCL.reset(makeSpecialCaseList("fun:b*\n"));
- EXPECT_FALSE(SCL->isIn(*Foo));
- EXPECT_TRUE(SCL->isIn(*Bar));
-
- SCL.reset(makeSpecialCaseList("fun:f*\n"
- "fun:bar\n"));
- EXPECT_TRUE(SCL->isIn(*Foo));
- EXPECT_TRUE(SCL->isIn(*Bar));
-
- SCL.reset(makeSpecialCaseList("fun:foo=functional\n"));
- EXPECT_TRUE(SCL->isIn(*Foo, "functional"));
- StringRef Category;
- EXPECT_FALSE(SCL->isIn(*Bar, "functional"));
-}
-
-TEST_F(SpecialCaseListTest, GlobalIsIn) {
- Module M("hello", Ctx);
- GlobalVariable *Foo = makeGlobal("foo", "t1", M);
- GlobalVariable *Bar = makeGlobal("bar", "t2", M);
-
- OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("global:foo\n"));
- EXPECT_TRUE(SCL->isIn(*Foo));
- EXPECT_FALSE(SCL->isIn(*Bar));
- EXPECT_FALSE(SCL->isIn(*Foo, "init"));
- EXPECT_FALSE(SCL->isIn(*Bar, "init"));
-
- SCL.reset(makeSpecialCaseList("global:foo=init\n"));
- EXPECT_FALSE(SCL->isIn(*Foo));
- EXPECT_FALSE(SCL->isIn(*Bar));
- EXPECT_TRUE(SCL->isIn(*Foo, "init"));
- EXPECT_FALSE(SCL->isIn(*Bar, "init"));
-
- SCL.reset(makeSpecialCaseList("global-init:foo\n"));
- EXPECT_FALSE(SCL->isIn(*Foo));
- EXPECT_FALSE(SCL->isIn(*Bar));
- EXPECT_TRUE(SCL->isIn(*Foo, "init"));
- EXPECT_FALSE(SCL->isIn(*Bar, "init"));
-
- SCL.reset(makeSpecialCaseList("type:t2=init\n"));
- EXPECT_FALSE(SCL->isIn(*Foo));
- EXPECT_FALSE(SCL->isIn(*Bar));
- EXPECT_FALSE(SCL->isIn(*Foo, "init"));
- EXPECT_TRUE(SCL->isIn(*Bar, "init"));
-
- SCL.reset(makeSpecialCaseList("global-init-type:t2\n"));
- EXPECT_FALSE(SCL->isIn(*Foo));
- EXPECT_FALSE(SCL->isIn(*Bar));
- EXPECT_FALSE(SCL->isIn(*Foo, "init"));
- EXPECT_TRUE(SCL->isIn(*Bar, "init"));
-
- SCL.reset(makeSpecialCaseList("src:hello=init\n"));
- EXPECT_FALSE(SCL->isIn(*Foo));
- EXPECT_FALSE(SCL->isIn(*Bar));
- EXPECT_TRUE(SCL->isIn(*Foo, "init"));
- EXPECT_TRUE(SCL->isIn(*Bar, "init"));
-
- SCL.reset(makeSpecialCaseList("global-init-src:hello\n"));
- EXPECT_FALSE(SCL->isIn(*Foo));
- EXPECT_FALSE(SCL->isIn(*Bar));
- EXPECT_TRUE(SCL->isIn(*Foo, "init"));
- EXPECT_TRUE(SCL->isIn(*Bar, "init"));
-}
-
-TEST_F(SpecialCaseListTest, AliasIsIn) {
- Module M("hello", Ctx);
- Function *Foo = makeFunction("foo", M);
- GlobalVariable *Bar = makeGlobal("bar", "t", M);
- GlobalAlias *FooAlias = makeAlias("fooalias", Foo);
- GlobalAlias *BarAlias = makeAlias("baralias", Bar);
-
- OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("fun:foo\n"));
- EXPECT_FALSE(SCL->isIn(*FooAlias));
- EXPECT_FALSE(SCL->isIn(*BarAlias));
-
- SCL.reset(makeSpecialCaseList("global:bar\n"));
- EXPECT_FALSE(SCL->isIn(*FooAlias));
- EXPECT_FALSE(SCL->isIn(*BarAlias));
-
- SCL.reset(makeSpecialCaseList("global:fooalias\n"));
- EXPECT_FALSE(SCL->isIn(*FooAlias));
- EXPECT_FALSE(SCL->isIn(*BarAlias));
-
- SCL.reset(makeSpecialCaseList("fun:fooalias\n"));
- EXPECT_TRUE(SCL->isIn(*FooAlias));
- EXPECT_FALSE(SCL->isIn(*BarAlias));
-
- SCL.reset(makeSpecialCaseList("global:baralias=init\n"));
- EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
- EXPECT_TRUE(SCL->isIn(*BarAlias, "init"));
-
- SCL.reset(makeSpecialCaseList("type:t=init\n"));
- EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
- EXPECT_TRUE(SCL->isIn(*BarAlias, "init"));
-
- SCL.reset(makeSpecialCaseList("fun:baralias=init\n"));
- EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
- EXPECT_FALSE(SCL->isIn(*BarAlias, "init"));
-}
-
-TEST_F(SpecialCaseListTest, Substring) {
- Module M("othello", Ctx);
- Function *F = makeFunction("tomfoolery", M);
- GlobalVariable *GV = makeGlobal("bartender", "t", M);
- GlobalAlias *GA1 = makeAlias("buffoonery", F);
- GlobalAlias *GA2 = makeAlias("foobar", GV);
-
- OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("src:hello\n"
- "fun:foo\n"
- "global:bar\n"));
- EXPECT_FALSE(SCL->isIn(M));
- EXPECT_FALSE(SCL->isIn(*F));
- EXPECT_FALSE(SCL->isIn(*GV));
- EXPECT_FALSE(SCL->isIn(*GA1));
- EXPECT_FALSE(SCL->isIn(*GA2));
-
- SCL.reset(makeSpecialCaseList("fun:*foo*\n"));
- EXPECT_TRUE(SCL->isIn(*F));
- EXPECT_TRUE(SCL->isIn(*GA1));
-}
-
-TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
- std::string Error;
- EXPECT_EQ(0, makeSpecialCaseList("badline", Error));
- EXPECT_EQ("Malformed line 1: 'badline'", Error);
- EXPECT_EQ(0, makeSpecialCaseList("src:bad[a-", Error));
- EXPECT_EQ("Malformed regex in line 1: 'bad[a-': invalid character range",
- Error);
- EXPECT_EQ(0, makeSpecialCaseList("src:a.c\n"
- "fun:fun(a\n",
- Error));
- EXPECT_EQ("Malformed regex in line 2: 'fun(a': parentheses not balanced",
- Error);
- EXPECT_EQ(0, SpecialCaseList::create("unexisting", Error));
- EXPECT_EQ(0U, Error.find("Can't open file 'unexisting':"));
-}
-
-TEST_F(SpecialCaseListTest, EmptySpecialCaseList) {
- OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList(""));
- Module M("foo", Ctx);
- EXPECT_FALSE(SCL->isIn(M));
-}
-
-}