1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00
llvm-mirror/unittests/Bitcode/BitstreamReaderTest.cpp
Serge Guelton b20ef5f960 Replace llvm::isPodLike<...> by llvm::is_trivially_copyable<...>
As noted in https://bugs.llvm.org/show_bug.cgi?id=36651, the specialization for
isPodLike<std::pair<...>> did not match the expectation of
std::is_trivially_copyable which makes the memcpy optimization invalid.

This patch renames the llvm::isPodLike trait into llvm::is_trivially_copyable.
Unfortunately std::is_trivially_copyable is not portable across compiler / STL
versions. So a portable version is provided too.

Note that the following specialization were invalid:

    std::pair<T0, T1>
    llvm::Optional<T>

Tests have been added to assert that former specialization are respected by the
standard usage of llvm::is_trivially_copyable, and that when a decent version
of std::is_trivially_copyable is available, llvm::is_trivially_copyable is
compared to std::is_trivially_copyable.

As of this patch, llvm::Optional is no longer considered trivially copyable,
even if T is. This is to be fixed in a later patch, as it has impact on a
long-running bug (see r347004)

Note that GCC warns about this UB, but this got silented by https://reviews.llvm.org/D50296.

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

llvm-svn: 351701
2019-01-20 21:19:56 +00:00

154 lines
4.4 KiB
C++

//===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
TEST(BitstreamReaderTest, AtEndOfStream) {
uint8_t Bytes[4] = {
0x00, 0x01, 0x02, 0x03
};
BitstreamCursor Cursor(Bytes);
EXPECT_FALSE(Cursor.AtEndOfStream());
(void)Cursor.Read(8);
EXPECT_FALSE(Cursor.AtEndOfStream());
(void)Cursor.Read(24);
EXPECT_TRUE(Cursor.AtEndOfStream());
Cursor.JumpToBit(0);
EXPECT_FALSE(Cursor.AtEndOfStream());
Cursor.JumpToBit(32);
EXPECT_TRUE(Cursor.AtEndOfStream());
}
TEST(BitstreamReaderTest, AtEndOfStreamJump) {
uint8_t Bytes[4] = {
0x00, 0x01, 0x02, 0x03
};
BitstreamCursor Cursor(Bytes);
Cursor.JumpToBit(32);
EXPECT_TRUE(Cursor.AtEndOfStream());
}
TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
BitstreamCursor Cursor(ArrayRef<uint8_t>{});
EXPECT_TRUE(Cursor.AtEndOfStream());
}
TEST(BitstreamReaderTest, getCurrentByteNo) {
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03};
SimpleBitstreamCursor Cursor(Bytes);
for (unsigned I = 0, E = 32; I != E; ++I) {
EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
(void)Cursor.Read(1);
}
EXPECT_EQ(4u, Cursor.getCurrentByteNo());
}
TEST(BitstreamReaderTest, getPointerToByte) {
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
SimpleBitstreamCursor Cursor(Bytes);
for (unsigned I = 0, E = 8; I != E; ++I) {
EXPECT_EQ(Bytes + I, Cursor.getPointerToByte(I, 1));
}
}
TEST(BitstreamReaderTest, getPointerToBit) {
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
SimpleBitstreamCursor Cursor(Bytes);
for (unsigned I = 0, E = 8; I != E; ++I) {
EXPECT_EQ(Bytes + I, Cursor.getPointerToBit(I * 8, 1));
}
}
TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
SmallVector<uint8_t, 1> BlobData;
for (unsigned I = 0, E = 1024; I != E; ++I)
BlobData.push_back(I);
// Try a bunch of different sizes.
const unsigned Magic = 0x12345678;
const unsigned BlockID = bitc::FIRST_APPLICATION_BLOCKID;
const unsigned RecordID = 1;
for (unsigned I = 0, BlobSize = 0, E = BlobData.size(); BlobSize < E;
BlobSize += ++I) {
StringRef BlobIn((const char *)BlobData.begin(), BlobSize);
// Write the bitcode.
SmallVector<char, 1> Buffer;
unsigned AbbrevID;
{
BitstreamWriter Stream(Buffer);
Stream.Emit(Magic, 32);
Stream.EnterSubblock(BlockID, 3);
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(RecordID));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
AbbrevID = Stream.EmitAbbrev(std::move(Abbrev));
unsigned Record[] = {RecordID};
Stream.EmitRecordWithBlob(AbbrevID, makeArrayRef(Record), BlobIn);
Stream.ExitBlock();
}
// Stream the buffer into the reader.
BitstreamCursor Stream(
ArrayRef<uint8_t>((const uint8_t *)Buffer.begin(), Buffer.size()));
// Header. Included in test so that we can run llvm-bcanalyzer to debug
// when there are problems.
ASSERT_EQ(Magic, Stream.Read(32));
// Block.
BitstreamEntry Entry =
Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
ASSERT_EQ(BitstreamEntry::SubBlock, Entry.Kind);
ASSERT_EQ(BlockID, Entry.ID);
ASSERT_FALSE(Stream.EnterSubBlock(BlockID));
// Abbreviation.
Entry = Stream.advance();
ASSERT_EQ(BitstreamEntry::Record, Entry.Kind);
ASSERT_EQ(AbbrevID, Entry.ID);
// Record.
StringRef BlobOut;
SmallVector<uint64_t, 1> Record;
ASSERT_EQ(RecordID, Stream.readRecord(Entry.ID, Record, &BlobOut));
EXPECT_TRUE(Record.empty());
EXPECT_EQ(BlobIn, BlobOut);
}
}
TEST(BitstreamReaderTest, shortRead) {
uint8_t Bytes[] = {8, 7, 6, 5, 4, 3, 2, 1};
for (unsigned I = 1; I != 8; ++I) {
SimpleBitstreamCursor Cursor(ArrayRef<uint8_t>(Bytes, I));
EXPECT_EQ(8ull, Cursor.Read(8));
}
}
static_assert(is_trivially_copyable<BitCodeAbbrevOp>::value,
"trivially copyable");
} // end anonymous namespace