diff options
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/ADT/BitVectorTest.cpp | 184 | ||||
-rw-r--r-- | unittests/Analysis/ProfileSummaryInfoTest.cpp | 8 | ||||
-rw-r--r-- | unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp | 1 | ||||
-rw-r--r-- | unittests/DebugInfo/PDB/TypeServerHandlerTest.cpp | 20 | ||||
-rw-r--r-- | unittests/Support/BinaryStreamTest.cpp | 29 | ||||
-rw-r--r-- | unittests/Support/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/Support/CrashRecoveryTest.cpp | 83 |
7 files changed, 310 insertions, 16 deletions
diff --git a/unittests/ADT/BitVectorTest.cpp b/unittests/ADT/BitVectorTest.cpp index faf362abc9d8c..d6a2075ca6094 100644 --- a/unittests/ADT/BitVectorTest.cpp +++ b/unittests/ADT/BitVectorTest.cpp @@ -182,15 +182,13 @@ TYPED_TEST(BitVectorTest, TrivialOperation) { EXPECT_TRUE(Vec.empty()); } -TYPED_TEST(BitVectorTest, FindOperations) { +TYPED_TEST(BitVectorTest, SimpleFindOps) { // Test finding in an empty BitVector. TypeParam A; EXPECT_EQ(-1, A.find_first()); EXPECT_EQ(-1, A.find_last()); EXPECT_EQ(-1, A.find_first_unset()); EXPECT_EQ(-1, A.find_last_unset()); - EXPECT_EQ(-1, A.find_next(0)); - EXPECT_EQ(-1, A.find_next_unset(0)); // Test finding next set and unset bits in a BitVector with multiple words A.resize(100); @@ -222,9 +220,10 @@ TYPED_TEST(BitVectorTest, FindOperations) { A.set(0, 100); EXPECT_EQ(100U, A.count()); EXPECT_EQ(0, A.find_first()); - EXPECT_EQ(99, A.find_last()); EXPECT_EQ(-1, A.find_first_unset()); EXPECT_EQ(-1, A.find_last_unset()); + EXPECT_EQ(99, A.find_last()); + EXPECT_EQ(99, A.find_next(98)); A.reset(0, 100); EXPECT_EQ(0U, A.count()); @@ -232,6 +231,7 @@ TYPED_TEST(BitVectorTest, FindOperations) { EXPECT_EQ(-1, A.find_last()); EXPECT_EQ(0, A.find_first_unset()); EXPECT_EQ(99, A.find_last_unset()); + EXPECT_EQ(99, A.find_next_unset(98)); // Also test with a vector that is small enough to fit in 1 word. A.resize(20); @@ -258,6 +258,153 @@ TYPED_TEST(BitVectorTest, FindOperations) { EXPECT_EQ(17, A.find_next_unset(15)); } +TEST(BitVectorTest, FindInRangeMultiWord) { + BitVector Vec; + + Vec.resize(200); + Vec.set(3, 7); + Vec.set(24, 35); + Vec.set(50, 70); + Vec.set(150); + Vec.set(152); + Vec.set(154); + + // find first + EXPECT_EQ(-1, Vec.find_first_in(0, 0)); + EXPECT_EQ(-1, Vec.find_first_in(24, 24)); + EXPECT_EQ(-1, Vec.find_first_in(7, 24)); + + EXPECT_EQ(3, Vec.find_first_in(0, 10)); + EXPECT_EQ(4, Vec.find_first_in(4, 10)); + EXPECT_EQ(150, Vec.find_first_in(100, 200)); + EXPECT_EQ(152, Vec.find_first_in(151, 200)); + EXPECT_EQ(154, Vec.find_first_in(153, 200)); + + EXPECT_EQ(-1, Vec.find_first_in(155, 200)); + Vec.set(199); + EXPECT_EQ(199, Vec.find_first_in(199, 200)); + Vec.reset(199); + + // find last + EXPECT_EQ(-1, Vec.find_last_in(0, 0)); + EXPECT_EQ(-1, Vec.find_last_in(24, 24)); + EXPECT_EQ(-1, Vec.find_last_in(7, 24)); + + EXPECT_EQ(6, Vec.find_last_in(0, 10)); + EXPECT_EQ(5, Vec.find_last_in(0, 6)); + EXPECT_EQ(154, Vec.find_last_in(100, 155)); + EXPECT_EQ(152, Vec.find_last_in(100, 154)); + EXPECT_EQ(150, Vec.find_last_in(100, 152)); + EXPECT_EQ(-1, Vec.find_last_in(100, 150)); + Vec.set(199); + EXPECT_EQ(199, Vec.find_last_in(199, 200)); + Vec.reset(199); + + // find first unset + EXPECT_EQ(-1, Vec.find_first_unset_in(0, 0)); + EXPECT_EQ(-1, Vec.find_first_unset_in(23, 23)); + EXPECT_EQ(-1, Vec.find_first_unset_in(24, 35)); + + EXPECT_EQ(0, Vec.find_first_unset_in(0, 10)); + EXPECT_EQ(1, Vec.find_first_unset_in(1, 10)); + EXPECT_EQ(7, Vec.find_first_unset_in(5, 25)); + EXPECT_EQ(151, Vec.find_first_unset_in(150, 200)); + EXPECT_EQ(151, Vec.find_first_unset_in(151, 200)); + EXPECT_EQ(153, Vec.find_first_unset_in(152, 200)); + EXPECT_EQ(153, Vec.find_first_unset_in(153, 200)); + EXPECT_EQ(155, Vec.find_first_unset_in(154, 200)); + EXPECT_EQ(155, Vec.find_first_unset_in(155, 200)); + EXPECT_EQ(199, Vec.find_first_unset_in(199, 200)); + + // find last unset + EXPECT_EQ(-1, Vec.find_last_unset_in(0, 0)); + EXPECT_EQ(-1, Vec.find_last_unset_in(23, 23)); + EXPECT_EQ(-1, Vec.find_last_unset_in(24, 35)); + + EXPECT_EQ(9, Vec.find_last_unset_in(0, 10)); + EXPECT_EQ(8, Vec.find_last_unset_in(0, 9)); + EXPECT_EQ(2, Vec.find_last_unset_in(0, 7)); + EXPECT_EQ(149, Vec.find_last_unset_in(100, 151)); + EXPECT_EQ(151, Vec.find_last_unset_in(100, 152)); + EXPECT_EQ(151, Vec.find_last_unset_in(100, 153)); + EXPECT_EQ(153, Vec.find_last_unset_in(100, 154)); + EXPECT_EQ(153, Vec.find_last_unset_in(100, 155)); + EXPECT_EQ(155, Vec.find_last_unset_in(100, 156)); + EXPECT_EQ(199, Vec.find_last_unset_in(199, 200)); +} + +TEST(BitVectorTest, FindInRangeSingleWord) { + // When the bit vector contains only a single word, this is slightly different + // than when the bit vector contains multiple words, because masks are applied + // to the front and back of the same word. So make sure this works. + BitVector Vec; + + Vec.resize(25); + Vec.set(2, 4); + Vec.set(6, 9); + Vec.set(12, 15); + Vec.set(19); + Vec.set(21); + Vec.set(23); + + // find first + EXPECT_EQ(-1, Vec.find_first_in(0, 0)); + EXPECT_EQ(-1, Vec.find_first_in(24, 24)); + EXPECT_EQ(-1, Vec.find_first_in(9, 12)); + + EXPECT_EQ(2, Vec.find_first_in(0, 10)); + EXPECT_EQ(6, Vec.find_first_in(4, 10)); + EXPECT_EQ(19, Vec.find_first_in(18, 25)); + EXPECT_EQ(21, Vec.find_first_in(20, 25)); + EXPECT_EQ(23, Vec.find_first_in(22, 25)); + EXPECT_EQ(-1, Vec.find_first_in(24, 25)); + + // find last + EXPECT_EQ(-1, Vec.find_last_in(0, 0)); + EXPECT_EQ(-1, Vec.find_last_in(24, 24)); + EXPECT_EQ(-1, Vec.find_last_in(9, 12)); + + EXPECT_EQ(8, Vec.find_last_in(0, 10)); + EXPECT_EQ(3, Vec.find_last_in(0, 6)); + EXPECT_EQ(23, Vec.find_last_in(18, 25)); + EXPECT_EQ(21, Vec.find_last_in(18, 23)); + EXPECT_EQ(19, Vec.find_last_in(18, 21)); + EXPECT_EQ(-1, Vec.find_last_in(18, 19)); + + // find first unset + EXPECT_EQ(-1, Vec.find_first_unset_in(0, 0)); + EXPECT_EQ(-1, Vec.find_first_unset_in(23, 23)); + EXPECT_EQ(-1, Vec.find_first_unset_in(6, 9)); + + EXPECT_EQ(0, Vec.find_first_unset_in(0, 6)); + EXPECT_EQ(1, Vec.find_first_unset_in(1, 6)); + EXPECT_EQ(9, Vec.find_first_unset_in(7, 13)); + EXPECT_EQ(18, Vec.find_first_unset_in(18, 25)); + EXPECT_EQ(20, Vec.find_first_unset_in(19, 25)); + EXPECT_EQ(20, Vec.find_first_unset_in(20, 25)); + EXPECT_EQ(22, Vec.find_first_unset_in(21, 25)); + EXPECT_EQ(22, Vec.find_first_unset_in(22, 25)); + EXPECT_EQ(24, Vec.find_first_unset_in(23, 25)); + EXPECT_EQ(24, Vec.find_first_unset_in(24, 25)); + + // find last unset + EXPECT_EQ(-1, Vec.find_last_unset_in(0, 0)); + EXPECT_EQ(-1, Vec.find_last_unset_in(23, 23)); + EXPECT_EQ(-1, Vec.find_last_unset_in(6, 9)); + + EXPECT_EQ(5, Vec.find_last_unset_in(0, 6)); + EXPECT_EQ(4, Vec.find_last_unset_in(0, 5)); + EXPECT_EQ(1, Vec.find_last_unset_in(0, 4)); + EXPECT_EQ(11, Vec.find_last_unset_in(7, 13)); + EXPECT_EQ(24, Vec.find_last_unset_in(18, 25)); + EXPECT_EQ(22, Vec.find_last_unset_in(18, 24)); + EXPECT_EQ(22, Vec.find_last_unset_in(18, 23)); + EXPECT_EQ(20, Vec.find_last_unset_in(18, 22)); + EXPECT_EQ(20, Vec.find_last_unset_in(18, 21)); + EXPECT_EQ(18, Vec.find_last_unset_in(18, 20)); + EXPECT_EQ(18, Vec.find_last_unset_in(18, 19)); +} + TYPED_TEST(BitVectorTest, CompoundAssignment) { TypeParam A; A.resize(10); @@ -660,5 +807,34 @@ TYPED_TEST(BitVectorTest, EmptyVector) { testEmpty(E); } +TYPED_TEST(BitVectorTest, Iterators) { + TypeParam Filled(10, true); + EXPECT_NE(Filled.set_bits_begin(), Filled.set_bits_end()); + unsigned Counter = 0; + for (unsigned Bit : Filled.set_bits()) + EXPECT_EQ(Bit, Counter++); + + TypeParam Empty; + EXPECT_EQ(Empty.set_bits_begin(), Empty.set_bits_end()); + for (unsigned Bit : Empty.set_bits()) { + (void)Bit; + EXPECT_TRUE(false); + } + + TypeParam ToFill(100, false); + ToFill.set(0); + EXPECT_NE(ToFill.set_bits_begin(), ToFill.set_bits_end()); + EXPECT_EQ(++ToFill.set_bits_begin(), ToFill.set_bits_end()); + EXPECT_EQ(*ToFill.set_bits_begin(), 0U); + ToFill.reset(0); + EXPECT_EQ(ToFill.set_bits_begin(), ToFill.set_bits_end()); + + const unsigned List[] = {1, 10, 25, 99}; + for (unsigned Num : List) + ToFill.set(Num); + unsigned i = 0; + for (unsigned Bit : ToFill.set_bits()) + EXPECT_EQ(List[i++], Bit); +} } #endif diff --git a/unittests/Analysis/ProfileSummaryInfoTest.cpp b/unittests/Analysis/ProfileSummaryInfoTest.cpp index 3454474f0376d..c9e4fc029dc01 100644 --- a/unittests/Analysis/ProfileSummaryInfoTest.cpp +++ b/unittests/Analysis/ProfileSummaryInfoTest.cpp @@ -102,6 +102,9 @@ TEST_F(ProfileSummaryInfoTest, TestNoProfile) { Function *F = M->getFunction("f"); ProfileSummaryInfo PSI = buildPSI(M.get()); + EXPECT_FALSE(PSI.hasProfileSummary()); + EXPECT_FALSE(PSI.hasSampleProfile()); + EXPECT_FALSE(PSI.hasInstrumentationProfile()); // In the absence of profiles, is{Hot|Cold}X methods should always return // false. EXPECT_FALSE(PSI.isHotCount(1000)); @@ -130,6 +133,7 @@ TEST_F(ProfileSummaryInfoTest, TestCommon) { Function *H = M->getFunction("h"); ProfileSummaryInfo PSI = buildPSI(M.get()); + EXPECT_TRUE(PSI.hasProfileSummary()); EXPECT_TRUE(PSI.isHotCount(400)); EXPECT_TRUE(PSI.isColdCount(2)); EXPECT_FALSE(PSI.isColdCount(100)); @@ -144,6 +148,8 @@ TEST_F(ProfileSummaryInfoTest, InstrProf) { auto M = makeLLVMModule("InstrProf"); Function *F = M->getFunction("f"); ProfileSummaryInfo PSI = buildPSI(M.get()); + EXPECT_TRUE(PSI.hasProfileSummary()); + EXPECT_TRUE(PSI.hasInstrumentationProfile()); BasicBlock &BB0 = F->getEntryBlock(); BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0); @@ -174,6 +180,8 @@ TEST_F(ProfileSummaryInfoTest, SampleProf) { auto M = makeLLVMModule("SampleProfile"); Function *F = M->getFunction("f"); ProfileSummaryInfo PSI = buildPSI(M.get()); + EXPECT_TRUE(PSI.hasProfileSummary()); + EXPECT_TRUE(PSI.hasSampleProfile()); BasicBlock &BB0 = F->getEntryBlock(); BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0); diff --git a/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp b/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp index fedb5978da816..9ff37e93b151b 100644 --- a/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp +++ b/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/SmallBitVector.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeSerializer.h" diff --git a/unittests/DebugInfo/PDB/TypeServerHandlerTest.cpp b/unittests/DebugInfo/PDB/TypeServerHandlerTest.cpp index 6995e8f9dded2..1a30dad7b3411 100644 --- a/unittests/DebugInfo/PDB/TypeServerHandlerTest.cpp +++ b/unittests/DebugInfo/PDB/TypeServerHandlerTest.cpp @@ -126,8 +126,8 @@ TEST_F(TypeServerHandlerTest, VisitRecordNoTypeServer) { Pipeline.addCallbackToPipeline(C1); Pipeline.addCallbackToPipeline(C2); - CVTypeVisitor Visitor(Pipeline); - EXPECT_NO_ERROR(Visitor.visitTypeRecord(TypeServerRecord)); + + EXPECT_NO_ERROR(codeview::visitTypeRecord(TypeServerRecord, Pipeline)); EXPECT_EQ(MockTypeVisitorCallbacks::State::VisitTypeEnd, C1.S); EXPECT_EQ(MockTypeVisitorCallbacks::State::VisitTypeEnd, C2.S); @@ -139,16 +139,16 @@ TEST_F(TypeServerHandlerTest, VisitRecordWithTypeServerOnce) { MockTypeServerHandler Handler(false); MockTypeVisitorCallbacks C1; - CVTypeVisitor Visitor(C1); - Visitor.addTypeServerHandler(Handler); // Our mock server returns true the first time. - EXPECT_NO_ERROR(Visitor.visitTypeRecord(TypeServerRecord)); + EXPECT_NO_ERROR(codeview::visitTypeRecord( + TypeServerRecord, C1, codeview::VDS_BytesExternal, &Handler)); EXPECT_TRUE(Handler.Handled); EXPECT_EQ(MockTypeVisitorCallbacks::State::Ready, C1.S); // And false the second time. - EXPECT_NO_ERROR(Visitor.visitTypeRecord(TypeServerRecord)); + EXPECT_NO_ERROR(codeview::visitTypeRecord( + TypeServerRecord, C1, codeview::VDS_BytesExternal, &Handler)); EXPECT_TRUE(Handler.Handled); EXPECT_EQ(MockTypeVisitorCallbacks::State::VisitTypeEnd, C1.S); } @@ -160,14 +160,14 @@ TEST_F(TypeServerHandlerTest, VisitRecordWithTypeServerAlways) { MockTypeServerHandler Handler(true); MockTypeVisitorCallbacks C1; - CVTypeVisitor Visitor(C1); - Visitor.addTypeServerHandler(Handler); - EXPECT_NO_ERROR(Visitor.visitTypeRecord(TypeServerRecord)); + EXPECT_NO_ERROR(codeview::visitTypeRecord( + TypeServerRecord, C1, codeview::VDS_BytesExternal, &Handler)); EXPECT_TRUE(Handler.Handled); EXPECT_EQ(MockTypeVisitorCallbacks::State::Ready, C1.S); - EXPECT_NO_ERROR(Visitor.visitTypeRecord(TypeServerRecord)); + EXPECT_NO_ERROR(codeview::visitTypeRecord( + TypeServerRecord, C1, codeview::VDS_BytesExternal, &Handler)); EXPECT_TRUE(Handler.Handled); EXPECT_EQ(MockTypeVisitorCallbacks::State::Ready, C1.S); } diff --git a/unittests/Support/BinaryStreamTest.cpp b/unittests/Support/BinaryStreamTest.cpp index 41567dad62260..ec3b0effc9e9a 100644 --- a/unittests/Support/BinaryStreamTest.cpp +++ b/unittests/Support/BinaryStreamTest.cpp @@ -16,6 +16,7 @@ #include "gtest/gtest.h" #include <unordered_map> +#include <utility> using namespace llvm; using namespace llvm::support; @@ -117,7 +118,7 @@ private: // Buffer is organized like this: // ------------------------------------------------- - // | N/2 | N/2+1 | ... | N-1 | 0 | 1 | ... | N-2-1 | + // | N/2 | N/2+1 | ... | N-1 | 0 | 1 | ... | N/2-1 | // ------------------------------------------------- // So reads from the beginning actually come from the middle. MutableArrayRef<uint8_t> Data; @@ -348,6 +349,30 @@ TEST_F(BinaryStreamTest, FixedStreamArray) { } } +// Ensure FixedStreamArrayIterator::operator-> works. +// Added for coverage of r302257. +TEST_F(BinaryStreamTest, FixedStreamArrayIteratorArrow) { + std::vector<std::pair<uint32_t, uint32_t>> Pairs = {{867, 5309}, {555, 1212}}; + ArrayRef<uint8_t> PairBytes(reinterpret_cast<uint8_t *>(Pairs.data()), + Pairs.size() * sizeof(Pairs[0])); + + initializeInput(PairBytes, alignof(uint32_t)); + + for (auto &Stream : Streams) { + ASSERT_EQ(InputData.size(), Stream.Input->getLength()); + + const FixedStreamArray<std::pair<uint32_t, uint32_t>> Array(*Stream.Input); + auto Iter = Array.begin(); + ASSERT_EQ(Pairs[0].first, Iter->first); + ASSERT_EQ(Pairs[0].second, Iter->second); + ++Iter; + ASSERT_EQ(Pairs[1].first, Iter->first); + ASSERT_EQ(Pairs[1].second, Iter->second); + ++Iter; + ASSERT_EQ(Array.end(), Iter); + } +} + // Test that VarStreamArray works correctly. TEST_F(BinaryStreamTest, VarStreamArray) { StringLiteral Strings("1. Test2. Longer Test3. Really Long Test4. Super " @@ -686,7 +711,7 @@ TEST_F(BinaryStreamTest, BinaryItemStream) { std::vector<Foo> Foos = {{1, 1.0}, {2, 2.0}, {3, 3.0}}; BumpPtrAllocator Allocator; for (const auto &F : Foos) { - uint8_t *Ptr = static_cast<uint8_t *>(Allocator.Allocate(sizeof(Foo), + uint8_t *Ptr = static_cast<uint8_t *>(Allocator.Allocate(sizeof(Foo), alignof(Foo))); MutableArrayRef<uint8_t> Buffer(Ptr, sizeof(Foo)); MutableBinaryByteStream Stream(Buffer, llvm::support::big); diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt index f8d3c1c9a8c77..e7f2f515d76a7 100644 --- a/unittests/Support/CMakeLists.txt +++ b/unittests/Support/CMakeLists.txt @@ -11,6 +11,7 @@ add_llvm_unittest(SupportTests BlockFrequencyTest.cpp BranchProbabilityTest.cpp CachePruningTest.cpp + CrashRecoveryTest.cpp Casting.cpp Chrono.cpp CommandLineTest.cpp diff --git a/unittests/Support/CrashRecoveryTest.cpp b/unittests/Support/CrashRecoveryTest.cpp new file mode 100644 index 0000000000000..dbb0db5767937 --- /dev/null +++ b/unittests/Support/CrashRecoveryTest.cpp @@ -0,0 +1,83 @@ +//===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CrashRecoveryContext.h" +#include "llvm/Support/Compiler.h" +#include "gtest/gtest.h" + +#ifdef LLVM_ON_WIN32 +#define WIN32_LEAN_AND_MEAN +#define NOGDI +#include <windows.h> +#endif + +using namespace llvm; +using namespace llvm::sys; + +static int GlobalInt = 0; +static void nullDeref() { *(volatile int *)nullptr = 0; } +static void incrementGlobal() { ++GlobalInt; } +static void llvmTrap() { LLVM_BUILTIN_TRAP; } + +TEST(CrashRecoveryTest, Basic) { + llvm::CrashRecoveryContext::Enable(); + GlobalInt = 0; + EXPECT_TRUE(CrashRecoveryContext().RunSafely(incrementGlobal)); + EXPECT_EQ(1, GlobalInt); + EXPECT_FALSE(CrashRecoveryContext().RunSafely(nullDeref)); + EXPECT_FALSE(CrashRecoveryContext().RunSafely(llvmTrap)); +} + +struct IncrementGlobalCleanup : CrashRecoveryContextCleanup { + IncrementGlobalCleanup(CrashRecoveryContext *CRC) + : CrashRecoveryContextCleanup(CRC) {} + virtual void recoverResources() { ++GlobalInt; } +}; + +static void noop() {} + +TEST(CrashRecoveryTest, Cleanup) { + llvm::CrashRecoveryContext::Enable(); + GlobalInt = 0; + { + CrashRecoveryContext CRC; + CRC.registerCleanup(new IncrementGlobalCleanup(&CRC)); + EXPECT_TRUE(CRC.RunSafely(noop)); + } // run cleanups + EXPECT_EQ(1, GlobalInt); + + GlobalInt = 0; + { + CrashRecoveryContext CRC; + CRC.registerCleanup(new IncrementGlobalCleanup(&CRC)); + EXPECT_FALSE(CRC.RunSafely(nullDeref)); + } // run cleanups + EXPECT_EQ(1, GlobalInt); +} + +#ifdef LLVM_ON_WIN32 +static void raiseIt() { + RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL); +} + +TEST(CrashRecoveryTest, RaiseException) { + llvm::CrashRecoveryContext::Enable(); + EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt)); +} + +static void outputString() { + OutputDebugStringA("output for debugger\n"); +} + +TEST(CrashRecoveryTest, CallOutputDebugString) { + llvm::CrashRecoveryContext::Enable(); + EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString)); +} + +#endif |