[llvm] r285773 - Bitcode: Change reader interface to take memory buffers.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 1 17:08:21 PDT 2016


Author: pcc
Date: Tue Nov  1 19:08:19 2016
New Revision: 285773

URL: http://llvm.org/viewvc/llvm-project?rev=285773&view=rev
Log:
Bitcode: Change reader interface to take memory buffers.

As proposed on llvm-dev:
http://lists.llvm.org/pipermail/llvm-dev/2016-October/106595.html

This change also fixes an API oddity where BitstreamCursor::Read() would
return zero for the first read past the end of the bitstream, but would
report_fatal_error for subsequent reads. Now we always report_fatal_error
for all reads past the end. Updated clients to check for the end of the
bitstream before reading from it.

I also needed to add padding to the invalid bitcode tests in
test/Bitcode/. This is because the streaming interface was not checking that
the file size is a multiple of 4.

Differential Revision: https://reviews.llvm.org/D26219

Modified:
    llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
    llvm/trunk/include/llvm/Bitcode/ReaderWriter.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/test/Bitcode/Inputs/invalid-array-operand-encoding.bc
    llvm/trunk/test/Bitcode/Inputs/invalid-code-len-width.bc
    llvm/trunk/test/Bitcode/Inputs/invalid-extractval-array-idx.bc
    llvm/trunk/test/Bitcode/Inputs/invalid-function-comdat-id.bc
    llvm/trunk/test/Bitcode/Inputs/invalid-fwdref-type-mismatch-2.bc
    llvm/trunk/test/Bitcode/Inputs/invalid-metadata-not-followed-named-node.bc
    llvm/trunk/test/Bitcode/Inputs/invalid-name-with-0-byte.bc
    llvm/trunk/test/Bitcode/Inputs/invalid-unexpected-eof.bc
    llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
    llvm/trunk/tools/llvm-dis/llvm-dis.cpp
    llvm/trunk/unittests/Bitcode/BitReaderTest.cpp
    llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp

Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original)
+++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Tue Nov  1 19:08:19 2016
@@ -15,13 +15,14 @@
 #ifndef LLVM_BITCODE_BITSTREAMREADER_H
 #define LLVM_BITCODE_BITSTREAMREADER_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Bitcode/BitCodes.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
-#include "llvm/Support/StreamingMemoryObject.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include <algorithm>
 #include <cassert>
 #include <climits>
@@ -50,32 +51,25 @@ public:
   };
 
 private:
-  std::unique_ptr<MemoryObject> BitcodeBytes;
+  ArrayRef<uint8_t> BitcodeBytes;
 
   std::vector<BlockInfo> BlockInfoRecords;
 
   /// This is set to true if we don't care about the block/record name
   /// information in the BlockInfo block. Only llvm-bcanalyzer uses this.
-  bool IgnoreBlockInfoNames;
+  bool IgnoreBlockInfoNames = true;
 
 public:
-  BitstreamReader() : IgnoreBlockInfoNames(true) {
-  }
-
-  BitstreamReader(const unsigned char *Start, const unsigned char *End)
-      : IgnoreBlockInfoNames(true) {
-    init(Start, End);
-  }
-
-  BitstreamReader(std::unique_ptr<MemoryObject> BitcodeBytes)
-      : BitcodeBytes(std::move(BitcodeBytes)), IgnoreBlockInfoNames(true) {}
-
-  void init(const unsigned char *Start, const unsigned char *End) {
-    assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
-    BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End));
-  }
+  BitstreamReader() = default;
+  BitstreamReader(ArrayRef<uint8_t> BitcodeBytes)
+      : BitcodeBytes(BitcodeBytes) {}
+  BitstreamReader(StringRef BitcodeBytes)
+      : BitcodeBytes(reinterpret_cast<const uint8_t *>(BitcodeBytes.data()),
+                     BitcodeBytes.size()) {}
+  BitstreamReader(MemoryBufferRef BitcodeBytes)
+      : BitstreamReader(BitcodeBytes.getBuffer()) {}
 
-  MemoryObject &getBitcodeBytes() { return *BitcodeBytes; }
+  ArrayRef<uint8_t> getBitcodeBytes() { return BitcodeBytes; }
 
   /// This is called by clients that want block/record name information.
   void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; }
@@ -131,9 +125,6 @@ class SimpleBitstreamCursor {
   BitstreamReader *R = nullptr;
   size_t NextChar = 0;
 
-  // The size of the bicode. 0 if we don't know it yet.
-  size_t Size = 0;
-
 public:
   /// This is the current data we have pulled from the stream but have not
   /// returned to the client. This is specifically and intentionally defined to
@@ -159,17 +150,11 @@ public:
 
   bool canSkipToPos(size_t pos) const {
     // pos can be skipped to if it is a valid address or one byte past the end.
-    return pos == 0 ||
-           R->getBitcodeBytes().isValidAddress(static_cast<uint64_t>(pos - 1));
+    return pos <= R->getBitcodeBytes().size();
   }
 
   bool AtEndOfStream() {
-    if (BitsInCurWord != 0)
-      return false;
-    if (Size != 0)
-      return Size <= NextChar;
-    fillCurWord();
-    return BitsInCurWord == 0;
+    return BitsInCurWord == 0 && R->getBitcodeBytes().size() <= NextChar;
   }
 
   /// Return the bit # of the bit we are reading.
@@ -218,7 +203,7 @@ public:
 
   /// Get a pointer into the bitstream at the specified byte offset.
   const uint8_t *getPointerToByte(uint64_t ByteNo, uint64_t NumBytes) {
-    return R->getBitcodeBytes().getPointer(ByteNo, NumBytes);
+    return R->getBitcodeBytes().data() + ByteNo;
   }
 
   /// Get a pointer into the bitstream at the specified bit offset.
@@ -230,26 +215,25 @@ public:
   }
 
   void fillCurWord() {
-    if (Size != 0 && NextChar >= Size)
+    ArrayRef<uint8_t> Buf = R->getBitcodeBytes();
+    if (NextChar >= Buf.size())
       report_fatal_error("Unexpected end of file");
 
     // Read the next word from the stream.
-    uint8_t Array[sizeof(word_t)] = {0};
-
-    uint64_t BytesRead =
-        R->getBitcodeBytes().readBytes(Array, sizeof(Array), NextChar);
-
-    // If we run out of data, stop at the end of the stream.
-    if (BytesRead == 0) {
+    const uint8_t *NextCharPtr = Buf.data() + NextChar;
+    unsigned BytesRead;
+    if (Buf.size() >= NextChar + sizeof(word_t)) {
+      BytesRead = sizeof(word_t);
+      CurWord =
+          support::endian::read<word_t, support::little, support::unaligned>(
+              NextCharPtr);
+    } else {
+      // Short read.
+      BytesRead = Buf.size() - NextChar;
       CurWord = 0;
-      BitsInCurWord = 0;
-      Size = NextChar;
-      return;
+      for (unsigned B = 0; B != BytesRead; ++B)
+        CurWord |= NextCharPtr[B] << (B * 8);
     }
-
-    CurWord =
-        support::endian::read<word_t, support::little, support::unaligned>(
-            Array);
     NextChar += BytesRead;
     BitsInCurWord = BytesRead * 8;
   }
@@ -278,9 +262,9 @@ public:
 
     fillCurWord();
 
-    // If we run out of data, stop at the end of the stream.
+    // If we run out of data, abort.
     if (BitsLeft > BitsInCurWord)
-      return 0;
+      report_fatal_error("Unexpected end of file");
 
     word_t R2 = CurWord & (~word_t(0) >> (BitsInWord - BitsLeft));
 
@@ -346,31 +330,7 @@ public:
   }
 
   /// Skip to the end of the file.
-  void skipToEnd() { NextChar = R->getBitcodeBytes().getExtent(); }
-
-  /// Prevent the cursor from reading past a byte boundary.
-  ///
-  /// Prevent the cursor from requesting byte reads past \c Limit.  This is
-  /// useful when working with a cursor on a StreamingMemoryObject, when it's
-  /// desirable to avoid invalidating the result of getPointerToByte().
-  ///
-  /// If \c Limit is on a word boundary, AtEndOfStream() will return true if
-  /// the cursor position reaches or exceeds \c Limit, regardless of the true
-  /// number of available bytes.  Otherwise, AtEndOfStream() returns true when
-  /// it reaches or exceeds the next word boundary.
-  void setArtificialByteLimit(uint64_t Limit) {
-    assert(getCurrentByteNo() < Limit && "Move cursor before lowering limit");
-
-    // Round to word boundary.
-    Limit = alignTo(Limit, sizeof(word_t));
-
-    // Only change size if the new one is lower.
-    if (!Size || Size > Limit)
-      Size = Limit;
-  }
-
-  /// Return the Size, if known.
-  uint64_t getSizeIfKnown() const { return Size; }
+  void skipToEnd() { NextChar = R->getBitcodeBytes().size(); }
 };
 
 /// When advancing through a bitstream cursor, each advance can discover a few
@@ -470,6 +430,9 @@ public:
   /// Advance the current bitstream, returning the next entry in the stream.
   BitstreamEntry advance(unsigned Flags = 0) {
     while (true) {
+      if (AtEndOfStream())
+        return BitstreamEntry::getError();
+
       unsigned Code = ReadCode();
       if (Code == bitc::END_BLOCK) {
         // Pop the end of the block unless Flags tells us not to.

Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/ReaderWriter.h?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h (original)
+++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h Tue Nov  1 19:08:19 2016
@@ -24,7 +24,6 @@
 
 namespace llvm {
   class BitstreamWriter;
-  class DataStreamer;
   class LLVMContext;
   class Module;
   class ModulePass;
@@ -47,13 +46,6 @@ namespace llvm {
                        LLVMContext &Context,
                        bool ShouldLazyLoadMetadata = false);
 
-  /// Read the header of the specified stream and prepare for lazy
-  /// deserialization and streaming of function bodies.
-  ErrorOr<std::unique_ptr<Module>>
-  getStreamedBitcodeModule(StringRef Name,
-                           std::unique_ptr<DataStreamer> Streamer,
-                           LLVMContext &Context);
-
   /// Read the header of the specified bitcode buffer and extract just the
   /// triple information. If successful, this returns a string. On error, this
   /// returns "".

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Nov  1 19:08:19 2016
@@ -61,14 +61,12 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataStream.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/StreamingMemoryObject.h"
 #include <algorithm>
 #include <cassert>
 #include <cstddef>
@@ -232,29 +230,19 @@ private:
 
 class BitcodeReaderBase {
 protected:
-  BitcodeReaderBase() = default;
   BitcodeReaderBase(MemoryBuffer *Buffer) : Buffer(Buffer) {}
 
   std::unique_ptr<MemoryBuffer> Buffer;
   std::unique_ptr<BitstreamReader> StreamFile;
   BitstreamCursor Stream;
 
-  std::error_code initStream(std::unique_ptr<DataStreamer> Streamer);
-  std::error_code initStreamFromBuffer();
-  std::error_code initLazyStream(std::unique_ptr<DataStreamer> Streamer);
+  std::error_code initStream();
 
   virtual std::error_code error(const Twine &Message) = 0;
   virtual ~BitcodeReaderBase() = default;
 };
 
-std::error_code
-BitcodeReaderBase::initStream(std::unique_ptr<DataStreamer> Streamer) {
-  if (Streamer)
-    return initLazyStream(std::move(Streamer));
-  return initStreamFromBuffer();
-}
-
-std::error_code BitcodeReaderBase::initStreamFromBuffer() {
+std::error_code BitcodeReaderBase::initStream() {
   const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart();
   const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
 
@@ -267,39 +255,12 @@ std::error_code BitcodeReaderBase::initS
     if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
       return error("Invalid bitcode wrapper header");
 
-  StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
+  StreamFile.reset(new BitstreamReader(ArrayRef<uint8_t>(BufPtr, BufEnd)));
   Stream.init(&*StreamFile);
 
   return std::error_code();
 }
 
-std::error_code
-BitcodeReaderBase::initLazyStream(std::unique_ptr<DataStreamer> Streamer) {
-  // Check and strip off the bitcode wrapper; BitstreamReader expects never to
-  // see it.
-  auto OwnedBytes =
-      llvm::make_unique<StreamingMemoryObject>(std::move(Streamer));
-  StreamingMemoryObject &Bytes = *OwnedBytes;
-  StreamFile = llvm::make_unique<BitstreamReader>(std::move(OwnedBytes));
-  Stream.init(&*StreamFile);
-
-  unsigned char buf[16];
-  if (Bytes.readBytes(buf, 16, 0) != 16)
-    return error("Invalid bitcode signature");
-
-  if (!isBitcode(buf, buf + 16))
-    return error("Invalid bitcode signature");
-
-  if (isBitcodeWrapper(buf, buf + 4)) {
-    const unsigned char *bitcodeStart = buf;
-    const unsigned char *bitcodeEnd = buf + 16;
-    SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
-    Bytes.dropLeadingBytes(bitcodeStart - buf);
-    Bytes.setKnownObjectSize(bitcodeEnd - bitcodeStart);
-  }
-  return std::error_code();
-}
-
 class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
   LLVMContext &Context;
   Module *TheModule = nullptr;
@@ -399,7 +360,6 @@ public:
   std::error_code error(const Twine &Message) override;
 
   BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context);
-  BitcodeReader(LLVMContext &Context);
   ~BitcodeReader() override { freeState(); }
 
   std::error_code materializeForwardReferencedFunctions();
@@ -414,8 +374,7 @@ public:
 
   /// \brief Main interface to parsing a bitcode buffer.
   /// \returns true if an error occurred.
-  std::error_code parseBitcodeInto(std::unique_ptr<DataStreamer> Streamer,
-                                   Module *M,
+  std::error_code parseBitcodeInto(Module *M,
                                    bool ShouldLazyLoadMetadata = false);
 
   /// \brief Cheap mechanism to just extract module triple
@@ -638,8 +597,7 @@ public:
 
   /// \brief Main interface to parsing a bitcode buffer.
   /// \returns true if an error occurred.
-  std::error_code parseSummaryIndexInto(std::unique_ptr<DataStreamer> Streamer,
-                                        ModuleSummaryIndex *I);
+  std::error_code parseSummaryIndexInto(ModuleSummaryIndex *I);
 
 private:
   std::error_code parseModule();
@@ -706,9 +664,6 @@ BitcodeReader::BitcodeReader(MemoryBuffe
     : BitcodeReaderBase(Buffer), Context(Context), ValueList(Context),
       MetadataList(Context) {}
 
-BitcodeReader::BitcodeReader(LLVMContext &Context)
-    : Context(Context), ValueList(Context), MetadataList(Context) {}
-
 std::error_code BitcodeReader::materializeForwardReferencedFunctions() {
   if (WillMaterializeAllForwardRefs)
     return std::error_code();
@@ -2166,10 +2121,6 @@ std::error_code BitcodeReader::parseMeta
   SimpleBitstreamCursor R(*StreamFile);
   R.jumpToPointer(Lengths.begin());
 
-  // Ensure that Blob doesn't get invalidated, even if this is reading from
-  // a StreamingMemoryObject with corrupt data.
-  R.setArtificialByteLimit(R.getCurrentByteNo() + StringsOffset);
-
   StringRef Strings = Blob.drop_front(StringsOffset);
   do {
     if (R.AtEndOfStream())
@@ -4203,12 +4154,11 @@ static bool hasValidBitcodeHeader(Bitstr
   return true;
 }
 
-std::error_code
-BitcodeReader::parseBitcodeInto(std::unique_ptr<DataStreamer> Streamer,
-                                Module *M, bool ShouldLazyLoadMetadata) {
+std::error_code BitcodeReader::parseBitcodeInto(Module *M,
+                                                bool ShouldLazyLoadMetadata) {
   TheModule = M;
 
-  if (std::error_code EC = initStream(std::move(Streamer)))
+  if (std::error_code EC = initStream())
     return EC;
 
   // Sniff for the signature.
@@ -4282,7 +4232,7 @@ ErrorOr<std::string> BitcodeReader::pars
 }
 
 ErrorOr<std::string> BitcodeReader::parseTriple() {
-  if (std::error_code EC = initStream(nullptr))
+  if (std::error_code EC = initStream())
     return EC;
 
   // Sniff for the signature.
@@ -4317,7 +4267,7 @@ ErrorOr<std::string> BitcodeReader::pars
 }
 
 ErrorOr<std::string> BitcodeReader::parseIdentificationBlock() {
-  if (std::error_code EC = initStream(nullptr))
+  if (std::error_code EC = initStream())
     return EC;
 
   // Sniff for the signature.
@@ -4367,7 +4317,7 @@ std::error_code BitcodeReader::parseGlob
 }
 
 ErrorOr<bool> BitcodeReader::hasObjCCategory() {
-  if (std::error_code EC = initStream(nullptr))
+  if (std::error_code EC = initStream())
     return EC;
 
   // Sniff for the signature.
@@ -5955,7 +5905,8 @@ std::error_code ModuleSummaryIndexBitcod
 ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader(
     MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler,
     bool CheckGlobalValSummaryPresenceOnly)
-    : BitcodeReaderBase(Buffer), DiagnosticHandler(std::move(DiagnosticHandler)),
+    : BitcodeReaderBase(Buffer),
+      DiagnosticHandler(std::move(DiagnosticHandler)),
       CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {}
 
 void ModuleSummaryIndexBitcodeReader::freeState() { Buffer = nullptr; }
@@ -6555,11 +6506,11 @@ std::error_code ModuleSummaryIndexBitcod
 }
 
 // Parse the function info index from the bitcode streamer into the given index.
-std::error_code ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(
-    std::unique_ptr<DataStreamer> Streamer, ModuleSummaryIndex *I) {
+std::error_code
+ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(ModuleSummaryIndex *I) {
   TheIndex = I;
 
-  if (std::error_code EC = initStream(std::move(Streamer)))
+  if (std::error_code EC = initStream())
     return EC;
 
   // Sniff for the signature.
@@ -6624,8 +6575,7 @@ const std::error_category &llvm::Bitcode
 //===----------------------------------------------------------------------===//
 
 static ErrorOr<std::unique_ptr<Module>>
-getBitcodeModuleImpl(std::unique_ptr<DataStreamer> Streamer, StringRef Name,
-                     BitcodeReader *R, LLVMContext &Context,
+getBitcodeModuleImpl(StringRef Name, BitcodeReader *R, LLVMContext &Context,
                      bool MaterializeAll, bool ShouldLazyLoadMetadata) {
   std::unique_ptr<Module> M = llvm::make_unique<Module>(Name, Context);
   M->setMaterializer(R);
@@ -6636,8 +6586,7 @@ getBitcodeModuleImpl(std::unique_ptr<Dat
   };
 
   // Delay parsing Metadata if ShouldLazyLoadMetadata is true.
-  if (std::error_code EC = R->parseBitcodeInto(std::move(Streamer), M.get(),
-                                               ShouldLazyLoadMetadata))
+  if (std::error_code EC = R->parseBitcodeInto(M.get(), ShouldLazyLoadMetadata))
     return cleanupOnError(EC);
 
   if (MaterializeAll) {
@@ -6667,7 +6616,7 @@ getLazyBitcodeModuleImpl(std::unique_ptr
   BitcodeReader *R = new BitcodeReader(Buffer.get(), Context);
 
   ErrorOr<std::unique_ptr<Module>> Ret =
-      getBitcodeModuleImpl(nullptr, Buffer->getBufferIdentifier(), R, Context,
+      getBitcodeModuleImpl(Buffer->getBufferIdentifier(), R, Context,
                            MaterializeAll, ShouldLazyLoadMetadata);
   if (!Ret)
     return Ret;
@@ -6683,17 +6632,6 @@ llvm::getLazyBitcodeModule(std::unique_p
                                   ShouldLazyLoadMetadata);
 }
 
-ErrorOr<std::unique_ptr<Module>>
-llvm::getStreamedBitcodeModule(StringRef Name,
-                               std::unique_ptr<DataStreamer> Streamer,
-                               LLVMContext &Context) {
-  std::unique_ptr<Module> M = llvm::make_unique<Module>(Name, Context);
-  BitcodeReader *R = new BitcodeReader(Context);
-
-  return getBitcodeModuleImpl(std::move(Streamer), Name, R, Context, false,
-                              false);
-}
-
 ErrorOr<std::unique_ptr<Module>> llvm::parseBitcodeFile(MemoryBufferRef Buffer,
                                                         LLVMContext &Context) {
   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
@@ -6746,7 +6684,7 @@ ErrorOr<std::unique_ptr<ModuleSummaryInd
     return EC;
   };
 
-  if (std::error_code EC = R.parseSummaryIndexInto(nullptr, Index.get()))
+  if (std::error_code EC = R.parseSummaryIndexInto(Index.get()))
     return cleanupOnError(EC);
 
   Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
@@ -6765,7 +6703,7 @@ bool llvm::hasGlobalValueSummary(
     return false;
   };
 
-  if (std::error_code EC = R.parseSummaryIndexInto(nullptr, nullptr))
+  if (std::error_code EC = R.parseSummaryIndexInto(nullptr))
     return cleanupOnError(EC);
 
   Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.

Modified: llvm/trunk/test/Bitcode/Inputs/invalid-array-operand-encoding.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/Inputs/invalid-array-operand-encoding.bc?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
Binary files llvm/trunk/test/Bitcode/Inputs/invalid-array-operand-encoding.bc (original) and llvm/trunk/test/Bitcode/Inputs/invalid-array-operand-encoding.bc Tue Nov  1 19:08:19 2016 differ

Modified: llvm/trunk/test/Bitcode/Inputs/invalid-code-len-width.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/Inputs/invalid-code-len-width.bc?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
Binary files llvm/trunk/test/Bitcode/Inputs/invalid-code-len-width.bc (original) and llvm/trunk/test/Bitcode/Inputs/invalid-code-len-width.bc Tue Nov  1 19:08:19 2016 differ

Modified: llvm/trunk/test/Bitcode/Inputs/invalid-extractval-array-idx.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/Inputs/invalid-extractval-array-idx.bc?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
Binary files llvm/trunk/test/Bitcode/Inputs/invalid-extractval-array-idx.bc (original) and llvm/trunk/test/Bitcode/Inputs/invalid-extractval-array-idx.bc Tue Nov  1 19:08:19 2016 differ

Modified: llvm/trunk/test/Bitcode/Inputs/invalid-function-comdat-id.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/Inputs/invalid-function-comdat-id.bc?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
Binary files llvm/trunk/test/Bitcode/Inputs/invalid-function-comdat-id.bc (original) and llvm/trunk/test/Bitcode/Inputs/invalid-function-comdat-id.bc Tue Nov  1 19:08:19 2016 differ

Modified: llvm/trunk/test/Bitcode/Inputs/invalid-fwdref-type-mismatch-2.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/Inputs/invalid-fwdref-type-mismatch-2.bc?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
Binary files llvm/trunk/test/Bitcode/Inputs/invalid-fwdref-type-mismatch-2.bc (original) and llvm/trunk/test/Bitcode/Inputs/invalid-fwdref-type-mismatch-2.bc Tue Nov  1 19:08:19 2016 differ

Modified: llvm/trunk/test/Bitcode/Inputs/invalid-metadata-not-followed-named-node.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/Inputs/invalid-metadata-not-followed-named-node.bc?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
Binary files llvm/trunk/test/Bitcode/Inputs/invalid-metadata-not-followed-named-node.bc (original) and llvm/trunk/test/Bitcode/Inputs/invalid-metadata-not-followed-named-node.bc Tue Nov  1 19:08:19 2016 differ

Modified: llvm/trunk/test/Bitcode/Inputs/invalid-name-with-0-byte.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/Inputs/invalid-name-with-0-byte.bc?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
Binary files llvm/trunk/test/Bitcode/Inputs/invalid-name-with-0-byte.bc (original) and llvm/trunk/test/Bitcode/Inputs/invalid-name-with-0-byte.bc Tue Nov  1 19:08:19 2016 differ

Modified: llvm/trunk/test/Bitcode/Inputs/invalid-unexpected-eof.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/Inputs/invalid-unexpected-eof.bc?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
--- llvm/trunk/test/Bitcode/Inputs/invalid-unexpected-eof.bc (original)
+++ llvm/trunk/test/Bitcode/Inputs/invalid-unexpected-eof.bc Tue Nov  1 19:08:19 2016
@@ -1 +1 @@
-BCÀÞ!00000000000000000000
\ No newline at end of file
+BCÀÞ!000000000000000000000
\ No newline at end of file

Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original)
+++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Tue Nov  1 19:08:19 2016
@@ -436,10 +436,6 @@ static bool decodeMetadataStringsBlob(Bi
   SimpleBitstreamCursor R(Reader);
   R.jumpToPointer(Lengths.begin());
 
-  // Ensure that Blob doesn't get invalidated, even if this is reading from a
-  // StreamingMemoryObject with corrupt data.
-  R.setArtificialByteLimit(R.getCurrentByteNo() + StringsOffset);
-
   StringRef Strings = Blob.drop_front(StringsOffset);
   do {
     if (R.AtEndOfStream())
@@ -735,7 +731,7 @@ static bool openBitcodeFile(StringRef Pa
       return ReportError("Invalid bitcode wrapper header");
   }
 
-  StreamFile = BitstreamReader(BufPtr, EndBufPtr);
+  StreamFile = BitstreamReader(ArrayRef<uint8_t>(BufPtr, EndBufPtr));
   Stream = BitstreamCursor(StreamFile);
   StreamFile.CollectBlockInfoNames();
 
@@ -814,7 +810,7 @@ static int AnalyzeBitcode() {
 
   if (Dump) outs() << "\n\n";
 
-  uint64_t BufferSizeBits = StreamFile.getBitcodeBytes().getExtent() * CHAR_BIT;
+  uint64_t BufferSizeBits = StreamFile.getBitcodeBytes().size() * CHAR_BIT;
   // Print a summary of the read file.
   outs() << "Summary of " << InputFilename << ":\n";
   outs() << "         Total size: ";

Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original)
+++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Tue Nov  1 19:08:19 2016
@@ -26,7 +26,6 @@
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Support/CommandLine.h"
-#include "llvm/Support/DataStream.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormattedStream.h"
@@ -139,34 +138,20 @@ static void diagnosticHandler(const Diag
 }
 
 static Expected<std::unique_ptr<Module>> openInputFile(LLVMContext &Context) {
-  if (MaterializeMetadata) {
-    ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
-        MemoryBuffer::getFileOrSTDIN(InputFilename);
-    if (!MBOrErr)
-      return errorCodeToError(MBOrErr.getError());
-    ErrorOr<std::unique_ptr<Module>> MOrErr =
-        getLazyBitcodeModule(std::move(*MBOrErr), Context,
-                             /*ShouldLazyLoadMetadata=*/true);
-    if (!MOrErr)
-      return errorCodeToError(MOrErr.getError());
+  ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+      MemoryBuffer::getFileOrSTDIN(InputFilename);
+  if (!MBOrErr)
+    return errorCodeToError(MBOrErr.getError());
+  ErrorOr<std::unique_ptr<Module>> MOrErr =
+      getLazyBitcodeModule(std::move(*MBOrErr), Context,
+                           /*ShouldLazyLoadMetadata=*/true);
+  if (!MOrErr)
+    return errorCodeToError(MOrErr.getError());
+  if (MaterializeMetadata)
     (*MOrErr)->materializeMetadata();
-    return std::move(*MOrErr);
-  } else {
-    std::string ErrorMessage;
-    std::unique_ptr<DataStreamer> Streamer =
-        getDataFileStreamer(InputFilename, &ErrorMessage);
-    if (!Streamer)
-      return make_error<StringError>(ErrorMessage, inconvertibleErrorCode());
-    std::string DisplayFilename;
-    if (InputFilename == "-")
-      DisplayFilename = "<stdin>";
-    else
-      DisplayFilename = InputFilename;
-    ErrorOr<std::unique_ptr<Module>> MOrErr =
-        getStreamedBitcodeModule(DisplayFilename, std::move(Streamer), Context);
+  else
     (*MOrErr)->materializeAll();
-    return std::move(*MOrErr);
-  }
+  return std::move(*MOrErr);
 }
 
 int main(int argc, char **argv) {

Modified: llvm/trunk/unittests/Bitcode/BitReaderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Bitcode/BitReaderTest.cpp?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
--- llvm/trunk/unittests/Bitcode/BitReaderTest.cpp (original)
+++ llvm/trunk/unittests/Bitcode/BitReaderTest.cpp Tue Nov  1 19:08:19 2016
@@ -18,11 +18,9 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Verifier.h"
-#include "llvm/Support/DataStream.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/StreamingMemoryObject.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -62,84 +60,6 @@ static std::unique_ptr<Module> getLazyMo
   return std::move(ModuleOrErr.get());
 }
 
-class BufferDataStreamer : public DataStreamer {
-  std::unique_ptr<MemoryBuffer> Buffer;
-  unsigned Pos = 0;
-  size_t GetBytes(unsigned char *Out, size_t Len) override {
-    StringRef Buf = Buffer->getBuffer();
-    size_t Left = Buf.size() - Pos;
-    Len = std::min(Left, Len);
-    memcpy(Out, Buffer->getBuffer().substr(Pos).data(), Len);
-    Pos += Len;
-    return Len;
-  }
-
-public:
-  BufferDataStreamer(std::unique_ptr<MemoryBuffer> Buffer)
-      : Buffer(std::move(Buffer)) {}
-};
-
-static std::unique_ptr<Module>
-getStreamedModuleFromAssembly(LLVMContext &Context, SmallString<1024> &Mem,
-                              const char *Assembly) {
-  writeModuleToBuffer(parseAssembly(Context, Assembly), Mem);
-  std::unique_ptr<MemoryBuffer> Buffer =
-      MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
-  auto Streamer = llvm::make_unique<BufferDataStreamer>(std::move(Buffer));
-  ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
-      getStreamedBitcodeModule("test", std::move(Streamer), Context);
-  return std::move(ModuleOrErr.get());
-}
-
-// Checks if we correctly detect eof if we try to read N bits when there are not
-// enough bits left on the input stream to read N bits, and we are using a data
-// streamer. In particular, it checks if we properly set the object size when
-// the eof is reached under such conditions.
-TEST(BitReaderTest, TestForEofAfterReadFailureOnDataStreamer) {
-  // Note: Because StreamingMemoryObject does a call to method GetBytes in it's
-  // constructor, using internal constant kChunkSize, we must fill the input
-  // with more characters than that amount.
-  static size_t InputSize = StreamingMemoryObject::kChunkSize + 5;
-  char *Text = new char[InputSize];
-  std::memset(Text, 'a', InputSize);
-  Text[InputSize - 1] = '\0';
-  StringRef Input(Text);
-
-  // Build bitsteam reader using data streamer.
-  auto MemoryBuf = MemoryBuffer::getMemBuffer(Input);
-  std::unique_ptr<DataStreamer> Streamer(
-      new BufferDataStreamer(std::move(MemoryBuf)));
-  auto OwnedBytes =
-      llvm::make_unique<StreamingMemoryObject>(std::move(Streamer));
-  auto Reader = llvm::make_unique<BitstreamReader>(std::move(OwnedBytes));
-  BitstreamCursor Cursor;
-  Cursor.init(Reader.get());
-
-  // Jump to two bytes before end of stream.
-  Cursor.JumpToBit((InputSize - 4) * CHAR_BIT);
-  // Try to read 4 bytes when only 2 are present, resulting in error value 0.
-  const size_t ReadErrorValue = 0;
-  EXPECT_EQ(ReadErrorValue, Cursor.Read(32));
-  // Should be at eof now.
-  EXPECT_TRUE(Cursor.AtEndOfStream());
-
-  delete[] Text;
-}
-
-TEST(BitReaderTest, MateralizeForwardRefWithStream) {
-  SmallString<1024> Mem;
-
-  LLVMContext Context;
-  std::unique_ptr<Module> M = getStreamedModuleFromAssembly(
-      Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
-                    "define void @func() {\n"
-                    "  unreachable\n"
-                    "bb:\n"
-                    "  unreachable\n"
-                    "}\n");
-  EXPECT_FALSE(M->getFunction("func")->empty());
-}
-
 // Tests that lazy evaluation can parse functions out of order.
 TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
   SmallString<1024> Mem;
@@ -216,6 +136,7 @@ TEST(BitReaderTest, MaterializeFunctions
                     "  unreachable\n"
                     "}\n");
   EXPECT_FALSE(verifyModule(*M, &dbgs()));
+  EXPECT_FALSE(M->getFunction("func")->empty());
 }
 
 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {

Modified: llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp?rev=285773&r1=285772&r2=285773&view=diff
==============================================================================
--- llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp (original)
+++ llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp Tue Nov  1 19:08:19 2016
@@ -10,33 +10,17 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
-#include "llvm/Support/StreamingMemoryObject.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
 
 namespace {
 
-class BufferStreamer : public DataStreamer {
-  StringRef Buffer;
-
-public:
-  BufferStreamer(StringRef Buffer) : Buffer(Buffer) {}
-  size_t GetBytes(unsigned char *OutBuffer, size_t Length) override {
-    if (Length >= Buffer.size())
-      Length = Buffer.size();
-
-    std::copy(Buffer.begin(), Buffer.begin() + Length, OutBuffer);
-    Buffer = Buffer.drop_front(Length);
-    return Length;
-  }
-};
-
 TEST(BitstreamReaderTest, AtEndOfStream) {
   uint8_t Bytes[4] = {
     0x00, 0x01, 0x02, 0x03
   };
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
+  BitstreamReader Reader(Bytes);
   BitstreamCursor Cursor(Reader);
 
   EXPECT_FALSE(Cursor.AtEndOfStream());
@@ -56,7 +40,7 @@ TEST(BitstreamReaderTest, AtEndOfStreamJ
   uint8_t Bytes[4] = {
     0x00, 0x01, 0x02, 0x03
   };
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
+  BitstreamReader Reader(Bytes);
   BitstreamCursor Cursor(Reader);
 
   Cursor.JumpToBit(32);
@@ -64,8 +48,7 @@ TEST(BitstreamReaderTest, AtEndOfStreamJ
 }
 
 TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
-  uint8_t Dummy = 0xFF;
-  BitstreamReader Reader(&Dummy, &Dummy);
+  BitstreamReader Reader(ArrayRef<uint8_t>{});
   BitstreamCursor Cursor(Reader);
 
   EXPECT_TRUE(Cursor.AtEndOfStream());
@@ -73,10 +56,10 @@ TEST(BitstreamReaderTest, AtEndOfStreamE
 
 TEST(BitstreamReaderTest, getCurrentByteNo) {
   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03};
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
+  BitstreamReader Reader(Bytes);
   SimpleBitstreamCursor Cursor(Reader);
 
-  for (unsigned I = 0, E = 33; I != E; ++I) {
+  for (unsigned I = 0, E = 32; I != E; ++I) {
     EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
     (void)Cursor.Read(1);
   }
@@ -85,7 +68,7 @@ TEST(BitstreamReaderTest, getCurrentByte
 
 TEST(BitstreamReaderTest, getPointerToByte) {
   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
+  BitstreamReader Reader(Bytes);
   SimpleBitstreamCursor Cursor(Reader);
 
   for (unsigned I = 0, E = 8; I != E; ++I) {
@@ -95,7 +78,7 @@ TEST(BitstreamReaderTest, getPointerToBy
 
 TEST(BitstreamReaderTest, getPointerToBit) {
   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
+  BitstreamReader Reader(Bytes);
   SimpleBitstreamCursor Cursor(Reader);
 
   for (unsigned I = 0, E = 8; I != E; ++I) {
@@ -105,7 +88,7 @@ TEST(BitstreamReaderTest, getPointerToBi
 
 TEST(BitstreamReaderTest, jumpToPointer) {
   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
+  BitstreamReader Reader(Bytes);
   SimpleBitstreamCursor Cursor(Reader);
 
   for (unsigned I : {0, 6, 2, 7}) {
@@ -114,68 +97,6 @@ TEST(BitstreamReaderTest, jumpToPointer)
   }
 }
 
-TEST(BitstreamReaderTest, setArtificialByteLimit) {
-  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-                     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
-  SimpleBitstreamCursor Cursor(Reader);
-
-  Cursor.setArtificialByteLimit(8);
-  EXPECT_EQ(8u, Cursor.getSizeIfKnown());
-  while (!Cursor.AtEndOfStream())
-    (void)Cursor.Read(1);
-
-  EXPECT_EQ(8u, Cursor.getCurrentByteNo());
-}
-
-TEST(BitstreamReaderTest, setArtificialByteLimitNotWordBoundary) {
-  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-                     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
-  SimpleBitstreamCursor Cursor(Reader);
-
-  Cursor.setArtificialByteLimit(5);
-  EXPECT_EQ(8u, Cursor.getSizeIfKnown());
-  while (!Cursor.AtEndOfStream())
-    (void)Cursor.Read(1);
-
-  EXPECT_EQ(8u, Cursor.getCurrentByteNo());
-}
-
-TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEnd) {
-  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-                     0x08, 0x09, 0x0a, 0x0b};
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
-  SimpleBitstreamCursor Cursor(Reader);
-
-  // The size of the memory object isn't known yet.  Set it too high and
-  // confirm that we don't read too far.
-  Cursor.setArtificialByteLimit(24);
-  EXPECT_EQ(24u, Cursor.getSizeIfKnown());
-  while (!Cursor.AtEndOfStream())
-    (void)Cursor.Read(1);
-
-  EXPECT_EQ(12u, Cursor.getCurrentByteNo());
-  EXPECT_EQ(12u, Cursor.getSizeIfKnown());
-}
-
-TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEndKnown) {
-  uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-                     0x08, 0x09, 0x0a, 0x0b};
-  BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
-  SimpleBitstreamCursor Cursor(Reader);
-
-  // Save the size of the memory object in the cursor.
-  while (!Cursor.AtEndOfStream())
-    (void)Cursor.Read(1);
-  EXPECT_EQ(12u, Cursor.getCurrentByteNo());
-  EXPECT_EQ(12u, Cursor.getSizeIfKnown());
-
-  Cursor.setArtificialByteLimit(20);
-  EXPECT_TRUE(Cursor.AtEndOfStream());
-  EXPECT_EQ(12u, Cursor.getSizeIfKnown());
-}
-
 TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
   SmallVector<uint8_t, 1> BlobData;
   for (unsigned I = 0, E = 1024; I != E; ++I)
@@ -208,9 +129,8 @@ TEST(BitstreamReaderTest, readRecordWith
     }
 
     // Stream the buffer into the reader.
-    BitstreamReader R(llvm::make_unique<StreamingMemoryObject>(
-        llvm::make_unique<BufferStreamer>(
-            StringRef(Buffer.begin(), Buffer.size()))));
+    BitstreamReader R(
+        ArrayRef<uint8_t>((const uint8_t *)Buffer.begin(), Buffer.size()));
     BitstreamCursor Stream(R);
 
     // Header.  Included in test so that we can run llvm-bcanalyzer to debug




More information about the llvm-commits mailing list