<commit_before>//===- llvm/unittest/DebugInfo/PDB/MappedBlockStreamTest.cpp --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <unordered_map>

#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/StreamRef.h"
#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::pdb;

namespace {

#define EXPECT_NO_ERROR(Err)                                                   \
  {                                                                            \
    auto E = std::move(Err);                                                   \
    EXPECT_FALSE(static_cast<bool>(E));                                        \
    if (E)                                                                     \
      consumeError(std::move(E));                                              \
  }

#define EXPECT_ERROR(Err)                                                      \
  {                                                                            \
    auto E = std::move(Err);                                                   \
    EXPECT_TRUE(static_cast<bool>(E));                                         \
    if (E)                                                                     \
      consumeError(std::move(E));                                              \
  }

static const uint32_t BlocksAry[] = {0, 1, 2, 5, 4, 3, 6, 7, 8, 9};
static const char DataAry[] = {'A', 'B', 'C', 'F', 'E',
                               'D', 'G', 'H', 'I', 'J'};

class DiscontiguousFile : public IPDBFile {
public:
  DiscontiguousFile()
      : Blocks(&BlocksAry[0], &BlocksAry[10]), Data(&DataAry[0], &DataAry[10]) {
  }

  virtual uint32_t getBlockSize() const override { return 1; }
  virtual uint32_t getBlockCount() const override { return 10; }
  virtual uint32_t getNumStreams() const override { return 1; }
  virtual uint32_t getStreamByteSize(uint32_t StreamIndex) const override {
    return getBlockCount() * getBlockSize();
  }
  virtual ArrayRef<uint32_t>
  getStreamBlockList(uint32_t StreamIndex) const override {
    if (StreamIndex != 0)
      return ArrayRef<uint32_t>();
    return Blocks;
  }
  virtual StringRef getBlockData(uint32_t BlockIndex,
                                 uint32_t NumBytes) const override {
    return StringRef(&Data[BlockIndex], NumBytes);
  }

private:
  std::vector<uint32_t> Blocks;
  std::vector<char> Data;
};

// Tests that a read which is entirely contained within a single block works
// and does not allocate.
TEST(MappedBlockStreamTest, ZeroCopyReadNoBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;
  EXPECT_NO_ERROR(R.readFixedString(Str, 1));
  EXPECT_EQ(Str, StringRef("A"));
  EXPECT_EQ(0, S.getNumBytesCopied());
}

// Tests that a read which outputs into a full destination buffer works and
// does not fail due to the length of the output buffer.
TEST(MappedBlockStreamTest, ReadOntoNonEmptyBuffer) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
  EXPECT_NO_ERROR(R.readFixedString(Str, 1));
  EXPECT_EQ(Str, StringRef("A"));
  EXPECT_EQ(0, S.getNumBytesCopied());
}

// Tests that a read which crosses a block boundary, but where the subsequent
// blocks are still contiguous in memory to the previous block works and does
// not allocate memory.
TEST(MappedBlockStreamTest, ZeroCopyReadContiguousBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;
  EXPECT_NO_ERROR(R.readFixedString(Str, 2));
  EXPECT_EQ(Str, StringRef("AB"));
  EXPECT_EQ(0, S.getNumBytesCopied());

  R.setOffset(6);
  EXPECT_NO_ERROR(R.readFixedString(Str, 4));
  EXPECT_EQ(Str, StringRef("GHIJ"));
  EXPECT_EQ(0, S.getNumBytesCopied());
}

// Tests that a read which crosses a block boundary and cannot be referenced
// contiguously works and allocates only the precise amount of bytes
// requested.
TEST(MappedBlockStreamTest, CopyReadNonContiguousBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;
  EXPECT_NO_ERROR(R.readFixedString(Str, 10));
  EXPECT_EQ(Str, StringRef("ABCDEFGHIJ"));
  EXPECT_EQ(10, S.getNumBytesCopied());
}

// Test that an out of bounds read which doesn't cross a block boundary
// fails and allocates no memory.
TEST(MappedBlockStreamTest, InvalidReadSizeNoBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;

  R.setOffset(10);
  EXPECT_ERROR(R.readFixedString(Str, 1));
  EXPECT_EQ(0, S.getNumBytesCopied());
}

// Test that an out of bounds read which crosses a contiguous block boundary
// fails and allocates no memory.
TEST(MappedBlockStreamTest, InvalidReadSizeContiguousBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;

  R.setOffset(6);
  EXPECT_ERROR(R.readFixedString(Str, 5));
  EXPECT_EQ(0, S.getNumBytesCopied());
}

// Test that an out of bounds read which crosses a discontiguous block
// boundary fails and allocates no memory.
TEST(MappedBlockStreamTest, InvalidReadSizeNonContiguousBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;

  EXPECT_ERROR(R.readFixedString(Str, 11));
  EXPECT_EQ(0, S.getNumBytesCopied());
}

} // end anonymous namespace<commit_msg>[PDB] Silence sign comparison warnings in MappedBlockStreamTest<commit_after>//===- llvm/unittest/DebugInfo/PDB/MappedBlockStreamTest.cpp --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <unordered_map>

#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/StreamRef.h"
#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::pdb;

namespace {

#define EXPECT_NO_ERROR(Err)                                                   \
  {                                                                            \
    auto E = std::move(Err);                                                   \
    EXPECT_FALSE(static_cast<bool>(E));                                        \
    if (E)                                                                     \
      consumeError(std::move(E));                                              \
  }

#define EXPECT_ERROR(Err)                                                      \
  {                                                                            \
    auto E = std::move(Err);                                                   \
    EXPECT_TRUE(static_cast<bool>(E));                                         \
    if (E)                                                                     \
      consumeError(std::move(E));                                              \
  }

static const uint32_t BlocksAry[] = {0, 1, 2, 5, 4, 3, 6, 7, 8, 9};
static const char DataAry[] = {'A', 'B', 'C', 'F', 'E',
                               'D', 'G', 'H', 'I', 'J'};

class DiscontiguousFile : public IPDBFile {
public:
  DiscontiguousFile()
      : Blocks(&BlocksAry[0], &BlocksAry[10]), Data(&DataAry[0], &DataAry[10]) {
  }

  virtual uint32_t getBlockSize() const override { return 1; }
  virtual uint32_t getBlockCount() const override { return 10; }
  virtual uint32_t getNumStreams() const override { return 1; }
  virtual uint32_t getStreamByteSize(uint32_t StreamIndex) const override {
    return getBlockCount() * getBlockSize();
  }
  virtual ArrayRef<uint32_t>
  getStreamBlockList(uint32_t StreamIndex) const override {
    if (StreamIndex != 0)
      return ArrayRef<uint32_t>();
    return Blocks;
  }
  virtual StringRef getBlockData(uint32_t BlockIndex,
                                 uint32_t NumBytes) const override {
    return StringRef(&Data[BlockIndex], NumBytes);
  }

private:
  std::vector<uint32_t> Blocks;
  std::vector<char> Data;
};

// Tests that a read which is entirely contained within a single block works
// and does not allocate.
TEST(MappedBlockStreamTest, ZeroCopyReadNoBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;
  EXPECT_NO_ERROR(R.readFixedString(Str, 1));
  EXPECT_EQ(Str, StringRef("A"));
  EXPECT_EQ(0U, S.getNumBytesCopied());
}

// Tests that a read which outputs into a full destination buffer works and
// does not fail due to the length of the output buffer.
TEST(MappedBlockStreamTest, ReadOntoNonEmptyBuffer) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
  EXPECT_NO_ERROR(R.readFixedString(Str, 1));
  EXPECT_EQ(Str, StringRef("A"));
  EXPECT_EQ(0U, S.getNumBytesCopied());
}

// Tests that a read which crosses a block boundary, but where the subsequent
// blocks are still contiguous in memory to the previous block works and does
// not allocate memory.
TEST(MappedBlockStreamTest, ZeroCopyReadContiguousBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;
  EXPECT_NO_ERROR(R.readFixedString(Str, 2));
  EXPECT_EQ(Str, StringRef("AB"));
  EXPECT_EQ(0U, S.getNumBytesCopied());

  R.setOffset(6);
  EXPECT_NO_ERROR(R.readFixedString(Str, 4));
  EXPECT_EQ(Str, StringRef("GHIJ"));
  EXPECT_EQ(0U, S.getNumBytesCopied());
}

// Tests that a read which crosses a block boundary and cannot be referenced
// contiguously works and allocates only the precise amount of bytes
// requested.
TEST(MappedBlockStreamTest, CopyReadNonContiguousBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;
  EXPECT_NO_ERROR(R.readFixedString(Str, 10));
  EXPECT_EQ(Str, StringRef("ABCDEFGHIJ"));
  EXPECT_EQ(10U, S.getNumBytesCopied());
}

// Test that an out of bounds read which doesn't cross a block boundary
// fails and allocates no memory.
TEST(MappedBlockStreamTest, InvalidReadSizeNoBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;

  R.setOffset(10);
  EXPECT_ERROR(R.readFixedString(Str, 1));
  EXPECT_EQ(0U, S.getNumBytesCopied());
}

// Test that an out of bounds read which crosses a contiguous block boundary
// fails and allocates no memory.
TEST(MappedBlockStreamTest, InvalidReadSizeContiguousBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;

  R.setOffset(6);
  EXPECT_ERROR(R.readFixedString(Str, 5));
  EXPECT_EQ(0U, S.getNumBytesCopied());
}

// Test that an out of bounds read which crosses a discontiguous block
// boundary fails and allocates no memory.
TEST(MappedBlockStreamTest, InvalidReadSizeNonContiguousBreak) {
  DiscontiguousFile F;
  MappedBlockStream S(0, F);
  StreamReader R(S);
  StringRef Str;

  EXPECT_ERROR(R.readFixedString(Str, 11));
  EXPECT_EQ(0U, S.getNumBytesCopied());
}

} // end anonymous namespace
{'fraction_non_alphanumeric': 0.12071067758230274, 'fraction_numerical': 0.01306392614527086, 'mean_word_length': 2.396332446021887, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 56, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3394944', 'n_tokens_mistral': 3493, 'n_tokens_neox': 3421, 'n_words': 873}