1//===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/ADT/SmallString.h"
11#include "llvm/ADT/STLExtras.h"
12#include "llvm/AsmParser/Parser.h"
13#include "llvm/Bitcode/BitstreamReader.h"
14#include "llvm/Bitcode/BitstreamWriter.h"
15#include "llvm/Bitcode/ReaderWriter.h"
16#include "llvm/IR/Constants.h"
17#include "llvm/IR/Instructions.h"
18#include "llvm/IR/LLVMContext.h"
19#include "llvm/IR/Module.h"
20#include "llvm/IR/Verifier.h"
21#include "llvm/Support/DataStream.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/MemoryBuffer.h"
24#include "llvm/Support/SourceMgr.h"
25#include "llvm/Support/StreamingMemoryObject.h"
26#include "gtest/gtest.h"
27
28using namespace llvm;
29
30namespace {
31
32std::unique_ptr<Module> parseAssembly(const char *Assembly) {
33  SMDiagnostic Error;
34  std::unique_ptr<Module> M =
35      parseAssemblyString(Assembly, Error, getGlobalContext());
36
37  std::string ErrMsg;
38  raw_string_ostream OS(ErrMsg);
39  Error.print("", OS);
40
41  // A failure here means that the test itself is buggy.
42  if (!M)
43    report_fatal_error(OS.str().c_str());
44
45  return M;
46}
47
48static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
49                                SmallVectorImpl<char> &Buffer) {
50  raw_svector_ostream OS(Buffer);
51  WriteBitcodeToFile(Mod.get(), OS);
52}
53
54static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
55                                                         SmallString<1024> &Mem,
56                                                         const char *Assembly) {
57  writeModuleToBuffer(parseAssembly(Assembly), Mem);
58  std::unique_ptr<MemoryBuffer> Buffer =
59      MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
60  ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
61      getLazyBitcodeModule(std::move(Buffer), Context);
62  return std::move(ModuleOrErr.get());
63}
64
65class BufferDataStreamer : public DataStreamer {
66  std::unique_ptr<MemoryBuffer> Buffer;
67  unsigned Pos = 0;
68  size_t GetBytes(unsigned char *Out, size_t Len) override {
69    StringRef Buf = Buffer->getBuffer();
70    size_t Left = Buf.size() - Pos;
71    Len = std::min(Left, Len);
72    memcpy(Out, Buffer->getBuffer().substr(Pos).data(), Len);
73    Pos += Len;
74    return Len;
75  }
76
77public:
78  BufferDataStreamer(std::unique_ptr<MemoryBuffer> Buffer)
79      : Buffer(std::move(Buffer)) {}
80};
81
82static std::unique_ptr<Module>
83getStreamedModuleFromAssembly(LLVMContext &Context, SmallString<1024> &Mem,
84                              const char *Assembly) {
85  writeModuleToBuffer(parseAssembly(Assembly), Mem);
86  std::unique_ptr<MemoryBuffer> Buffer =
87      MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
88  auto Streamer = llvm::make_unique<BufferDataStreamer>(std::move(Buffer));
89  ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
90      getStreamedBitcodeModule("test", std::move(Streamer), Context);
91  return std::move(ModuleOrErr.get());
92}
93
94// Checks if we correctly detect eof if we try to read N bits when there are not
95// enough bits left on the input stream to read N bits, and we are using a data
96// streamer. In particular, it checks if we properly set the object size when
97// the eof is reached under such conditions.
98TEST(BitReaderTest, TestForEofAfterReadFailureOnDataStreamer) {
99  // Note: Because StreamingMemoryObject does a call to method GetBytes in it's
100  // constructor, using internal constant kChunkSize, we must fill the input
101  // with more characters than that amount.
102  static size_t InputSize = StreamingMemoryObject::kChunkSize + 5;
103  char *Text = new char[InputSize];
104  std::memset(Text, 'a', InputSize);
105  Text[InputSize - 1] = '\0';
106  StringRef Input(Text);
107
108  // Build bitsteam reader using data streamer.
109  auto MemoryBuf = MemoryBuffer::getMemBuffer(Input);
110  std::unique_ptr<DataStreamer> Streamer(
111      new BufferDataStreamer(std::move(MemoryBuf)));
112  auto OwnedBytes =
113      llvm::make_unique<StreamingMemoryObject>(std::move(Streamer));
114  auto Reader = llvm::make_unique<BitstreamReader>(std::move(OwnedBytes));
115  BitstreamCursor Cursor;
116  Cursor.init(Reader.get());
117
118  // Jump to two bytes before end of stream.
119  Cursor.JumpToBit((InputSize - 4) * CHAR_BIT);
120  // Try to read 4 bytes when only 2 are present, resulting in error value 0.
121  const size_t ReadErrorValue = 0;
122  EXPECT_EQ(ReadErrorValue, Cursor.Read(32));
123  // Should be at eof now.
124  EXPECT_TRUE(Cursor.AtEndOfStream());
125
126  delete[] Text;
127}
128
129TEST(BitReaderTest, MateralizeForwardRefWithStream) {
130  SmallString<1024> Mem;
131
132  LLVMContext Context;
133  std::unique_ptr<Module> M = getStreamedModuleFromAssembly(
134      Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
135                    "define void @func() {\n"
136                    "  unreachable\n"
137                    "bb:\n"
138                    "  unreachable\n"
139                    "}\n");
140  EXPECT_FALSE(M->getFunction("func")->empty());
141}
142
143// Tests that lazy evaluation can parse functions out of order.
144TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
145  SmallString<1024> Mem;
146  LLVMContext Context;
147  std::unique_ptr<Module> M = getLazyModuleFromAssembly(
148      Context, Mem, "define void @f() {\n"
149                    "  unreachable\n"
150                    "}\n"
151                    "define void @g() {\n"
152                    "  unreachable\n"
153                    "}\n"
154                    "define void @h() {\n"
155                    "  unreachable\n"
156                    "}\n"
157                    "define void @j() {\n"
158                    "  unreachable\n"
159                    "}\n");
160  EXPECT_FALSE(verifyModule(*M, &dbgs()));
161
162  Function *F = M->getFunction("f");
163  Function *G = M->getFunction("g");
164  Function *H = M->getFunction("h");
165  Function *J = M->getFunction("j");
166
167  // Initially all functions are not materialized (no basic blocks).
168  EXPECT_TRUE(F->empty());
169  EXPECT_TRUE(G->empty());
170  EXPECT_TRUE(H->empty());
171  EXPECT_TRUE(J->empty());
172  EXPECT_FALSE(verifyModule(*M, &dbgs()));
173
174  // Materialize h.
175  H->materialize();
176  EXPECT_TRUE(F->empty());
177  EXPECT_TRUE(G->empty());
178  EXPECT_FALSE(H->empty());
179  EXPECT_TRUE(J->empty());
180  EXPECT_FALSE(verifyModule(*M, &dbgs()));
181
182  // Materialize g.
183  G->materialize();
184  EXPECT_TRUE(F->empty());
185  EXPECT_FALSE(G->empty());
186  EXPECT_FALSE(H->empty());
187  EXPECT_TRUE(J->empty());
188  EXPECT_FALSE(verifyModule(*M, &dbgs()));
189
190  // Materialize j.
191  J->materialize();
192  EXPECT_TRUE(F->empty());
193  EXPECT_FALSE(G->empty());
194  EXPECT_FALSE(H->empty());
195  EXPECT_FALSE(J->empty());
196  EXPECT_FALSE(verifyModule(*M, &dbgs()));
197
198  // Materialize f.
199  F->materialize();
200  EXPECT_FALSE(F->empty());
201  EXPECT_FALSE(G->empty());
202  EXPECT_FALSE(H->empty());
203  EXPECT_FALSE(J->empty());
204  EXPECT_FALSE(verifyModule(*M, &dbgs()));
205}
206
207TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
208  SmallString<1024> Mem;
209
210  LLVMContext Context;
211  std::unique_ptr<Module> M = getLazyModuleFromAssembly(
212      Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
213                    "define void @func() {\n"
214                    "  unreachable\n"
215                    "bb:\n"
216                    "  unreachable\n"
217                    "}\n");
218  EXPECT_FALSE(verifyModule(*M, &dbgs()));
219}
220
221TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
222  SmallString<1024> Mem;
223
224  LLVMContext Context;
225  std::unique_ptr<Module> M = getLazyModuleFromAssembly(
226      Context, Mem, "define i8* @before() {\n"
227                    "  ret i8* blockaddress(@func, %bb)\n"
228                    "}\n"
229                    "define void @other() {\n"
230                    "  unreachable\n"
231                    "}\n"
232                    "define void @func() {\n"
233                    "  unreachable\n"
234                    "bb:\n"
235                    "  unreachable\n"
236                    "}\n");
237  EXPECT_TRUE(M->getFunction("before")->empty());
238  EXPECT_TRUE(M->getFunction("func")->empty());
239  EXPECT_FALSE(verifyModule(*M, &dbgs()));
240
241  // Materialize @before, pulling in @func.
242  EXPECT_FALSE(M->getFunction("before")->materialize());
243  EXPECT_FALSE(M->getFunction("func")->empty());
244  EXPECT_TRUE(M->getFunction("other")->empty());
245  EXPECT_FALSE(verifyModule(*M, &dbgs()));
246}
247
248TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
249  SmallString<1024> Mem;
250
251  LLVMContext Context;
252  std::unique_ptr<Module> M = getLazyModuleFromAssembly(
253      Context, Mem, "define void @func() {\n"
254                    "  unreachable\n"
255                    "bb:\n"
256                    "  unreachable\n"
257                    "}\n"
258                    "define void @other() {\n"
259                    "  unreachable\n"
260                    "}\n"
261                    "define i8* @after() {\n"
262                    "  ret i8* blockaddress(@func, %bb)\n"
263                    "}\n");
264  EXPECT_TRUE(M->getFunction("after")->empty());
265  EXPECT_TRUE(M->getFunction("func")->empty());
266  EXPECT_FALSE(verifyModule(*M, &dbgs()));
267
268  // Materialize @after, pulling in @func.
269  EXPECT_FALSE(M->getFunction("after")->materialize());
270  EXPECT_FALSE(M->getFunction("func")->empty());
271  EXPECT_TRUE(M->getFunction("other")->empty());
272  EXPECT_FALSE(verifyModule(*M, &dbgs()));
273}
274
275} // end namespace
276