diff --git a/llvm/lib/Support/BinaryStreamWriter.cpp b/llvm/lib/Support/BinaryStreamWriter.cpp --- a/llvm/lib/Support/BinaryStreamWriter.cpp +++ b/llvm/lib/Support/BinaryStreamWriter.cpp @@ -94,10 +94,11 @@ Error BinaryStreamWriter::padToAlignment(uint32_t Align) { uint64_t NewOffset = alignTo(Offset, Align); - if (NewOffset > getLength()) - return make_error(stream_error_code::stream_too_short); + const uint64_t ZerosSize = 64; + static constexpr char Zeros[ZerosSize] = {}; while (Offset < NewOffset) - if (auto EC = writeInteger('\0')) - return EC; + if (auto E = writeArray( + ArrayRef(Zeros, std::min(ZerosSize, NewOffset - Offset)))) + return E; return Error::success(); } diff --git a/llvm/unittests/Support/BinaryStreamTest.cpp b/llvm/unittests/Support/BinaryStreamTest.cpp --- a/llvm/unittests/Support/BinaryStreamTest.cpp +++ b/llvm/unittests/Support/BinaryStreamTest.cpp @@ -807,7 +807,7 @@ } } -TEST_F(BinaryStreamTest, StringWriterStrings) { +TEST_F(BinaryStreamTest, StreamWriterStrings) { StringRef Strings[] = {"First", "Second", "Third", "Fourth"}; size_t Length = 0; @@ -831,6 +831,47 @@ } } +TEST_F(BinaryStreamTest, StreamWriterPadToAlignment) { + // This test may seem excessive but it is checking for past bugs and corner + // cases by making sure that the stream is allowed to grow and that + // both multiple pad chunks and single chunk extensions work. + AppendingBinaryByteStream Stream(support::little); + BinaryStreamWriter Writer(Stream); + + // Offset 0: '0' + EXPECT_THAT_ERROR(Writer.writeInteger('0'), Succeeded()); + // Offset 1..110: 0 + EXPECT_THAT_ERROR(Writer.padToAlignment(111), Succeeded()); + // Offset 111: '*' + EXPECT_THAT_ERROR(Writer.writeInteger('*'), Succeeded()); + // Offset 112..120: 0 + EXPECT_THAT_ERROR(Writer.padToAlignment(11), Succeeded()); + + BinaryStreamReader Reader(Stream); + char c; + // Offset 0 + EXPECT_THAT_ERROR(Reader.readInteger(c), Succeeded()); + EXPECT_EQ('0', c); + // Offset 1..110 + for (int i = 0; i < 110; ++i) { + char c; + EXPECT_THAT_ERROR(Reader.readInteger(c), Succeeded()); + EXPECT_EQ('\0', c); + } + // Offset 111 + EXPECT_THAT_ERROR(Reader.readInteger(c), Succeeded()); + EXPECT_EQ('*', c); + // Offset 112..120 + for (int i = 0; i < 9; ++i) { + char c; + EXPECT_THAT_ERROR(Reader.readInteger(c), Succeeded()); + EXPECT_EQ('\0', c); + } + + // EOF. + EXPECT_THAT_ERROR(Reader.readInteger(c), Failed()); +} + TEST_F(BinaryStreamTest, StreamWriterAppend) { StringRef Strings[] = {"First", "Second", "Third", "Fourth"}; AppendingBinaryByteStream Stream(support::little);