Use r2 when encoding tls on ppc32. Fixes PR18305.
[oota-llvm.git] / unittests / Support / MemoryBufferTest.cpp
index 1d9f482c519db288416216406796bd196b1b1595..2b8806c394f3451c11110be075ca21c285aa43bc 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#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;
 
+namespace {
+
 class MemoryBufferTest : public testing::Test {
 protected:
   MemoryBufferTest()
@@ -25,13 +29,18 @@ protected:
 
   virtual void SetUp() { }
 
+  /// Common testing for different modes of getOpenFileSlice.
+  /// Creates a temporary file with known contents, and uses
+  /// MemoryBuffer::getOpenFileSlice to map it.
+  /// If \p Reopen is true, the file is closed after creating and reopened
+  /// anew before using MemoryBuffer.
+  void testGetOpenFileSlice(bool Reopen);
+
   typedef OwningPtr<MemoryBuffer> OwningBuffer;
 
   std::string data;
 };
 
-namespace {
-
 TEST_F(MemoryBufferTest, get) {
   // Default name and null-terminator flag
   OwningBuffer MB1(MemoryBuffer::getMemBuffer(data));
@@ -56,6 +65,28 @@ TEST_F(MemoryBufferTest, get) {
   EXPECT_EQ("this is some data", data);
 }
 
+TEST_F(MemoryBufferTest, NullTerminator4K) {
+  // Test that a file with size that is a multiple of the page size can be null
+  // terminated correctly by MemoryBuffer.
+  int TestFD;
+  SmallString<64> TestPath;
+  sys::fs::createTemporaryFile("MemoryBufferTest_NullTerminator4K", "temp",
+                               TestFD, TestPath);
+  raw_fd_ostream OF(TestFD, true, /*unbuffered=*/true);
+  for (unsigned i = 0; i < 4096 / 16; ++i) {
+    OF << "0123456789abcdef";
+  }
+  OF.close();
+
+  OwningPtr<MemoryBuffer> MB;
+  error_code EC = MemoryBuffer::getFile(TestPath.c_str(), MB);
+  ASSERT_FALSE(EC);
+
+  const char *BufData = MB->getBufferStart();
+  EXPECT_EQ('f', BufData[4095]);
+  EXPECT_EQ('\0', BufData[4096]);
+}
+
 TEST_F(MemoryBufferTest, copy) {
   // copy with no name
   OwningBuffer MBC1(MemoryBuffer::getMemBufferCopy(data));
@@ -95,4 +126,46 @@ TEST_F(MemoryBufferTest, make_new) {
     EXPECT_EQ(0, Four->getBufferStart()[0]);
 }
 
+void MemoryBufferTest::testGetOpenFileSlice(bool Reopen) {
+  // Test that MemoryBuffer::getOpenFile works properly when no null
+  // terminator is requested and the size is large enough to trigger
+  // the usage of memory mapping.
+  int TestFD;
+  SmallString<64> TestPath;
+  // Create a temporary file and write data into it.
+  sys::fs::createTemporaryFile("prefix", "temp", TestFD, TestPath);
+  // OF is responsible for closing the file; If the file is not
+  // reopened, it will be unbuffered so that the results are
+  // immediately visible through the fd.
+  raw_fd_ostream OF(TestFD, true, !Reopen);
+  for (int i = 0; i < 60000; ++i) {
+    OF << "0123456789";
+  }
+
+  if (Reopen) {
+    OF.close();
+    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
+                                                 );
+  EXPECT_FALSE(EC);
+
+  StringRef BufData = Buf->getBuffer();
+  EXPECT_EQ(BufData.size(), 40000U);
+  EXPECT_EQ(BufData[0], '0');
+  EXPECT_EQ(BufData[9], '9');
+}
+
+TEST_F(MemoryBufferTest, getOpenFileNoReopen) {
+  testGetOpenFileSlice(false);
+}
+
+TEST_F(MemoryBufferTest, getOpenFileReopened) {
+  testGetOpenFileSlice(true);
+}
+
 }