Handle forward referenced function when streaming bitcode.
[oota-llvm.git] / unittests / Bitcode / BitReaderTest.cpp
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/BitstreamWriter.h"
14 #include "llvm/Bitcode/ReaderWriter.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/IR/Verifier.h"
20 #include "llvm/Support/DataStream.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/MemoryBuffer.h"
23 #include "llvm/Support/SourceMgr.h"
24 #include "gtest/gtest.h"
25
26 using namespace llvm;
27
28 namespace {
29
30 std::unique_ptr<Module> parseAssembly(const char *Assembly) {
31   SMDiagnostic Error;
32   std::unique_ptr<Module> M =
33       parseAssemblyString(Assembly, Error, getGlobalContext());
34
35   std::string ErrMsg;
36   raw_string_ostream OS(ErrMsg);
37   Error.print("", OS);
38
39   // A failure here means that the test itself is buggy.
40   if (!M)
41     report_fatal_error(OS.str().c_str());
42
43   return M;
44 }
45
46 static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
47                                 SmallVectorImpl<char> &Buffer) {
48   raw_svector_ostream OS(Buffer);
49   WriteBitcodeToFile(Mod.get(), OS);
50 }
51
52 static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
53                                                          SmallString<1024> &Mem,
54                                                          const char *Assembly) {
55   writeModuleToBuffer(parseAssembly(Assembly), Mem);
56   std::unique_ptr<MemoryBuffer> Buffer =
57       MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
58   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
59       getLazyBitcodeModule(std::move(Buffer), Context);
60   return std::move(ModuleOrErr.get());
61 }
62
63 class BufferDataStreamer : public DataStreamer {
64   std::unique_ptr<MemoryBuffer> Buffer;
65   unsigned Pos = 0;
66   size_t GetBytes(unsigned char *Out, size_t Len) override {
67     StringRef Buf = Buffer->getBuffer();
68     size_t Left = Buf.size() - Pos;
69     Len = std::min(Left, Len);
70     memcpy(Out, Buffer->getBuffer().substr(Pos).data(), Len);
71     Pos += Len;
72     return Len;
73   }
74
75 public:
76   BufferDataStreamer(std::unique_ptr<MemoryBuffer> Buffer)
77       : Buffer(std::move(Buffer)) {}
78 };
79
80 static std::unique_ptr<Module>
81 getStreamedModuleFromAssembly(LLVMContext &Context, SmallString<1024> &Mem,
82                               const char *Assembly) {
83   writeModuleToBuffer(parseAssembly(Assembly), Mem);
84   std::unique_ptr<MemoryBuffer> Buffer =
85       MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
86   auto Streamer = make_unique<BufferDataStreamer>(std::move(Buffer));
87   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
88       getStreamedBitcodeModule("test", std::move(Streamer), Context);
89   return std::move(ModuleOrErr.get());
90 }
91
92 TEST(BitReaderTest, MateralizeForwardRefWithStream) {
93   SmallString<1024> Mem;
94
95   LLVMContext Context;
96   std::unique_ptr<Module> M = getStreamedModuleFromAssembly(
97       Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
98                     "define void @func() {\n"
99                     "  unreachable\n"
100                     "bb:\n"
101                     "  unreachable\n"
102                     "}\n");
103   EXPECT_FALSE(M->getFunction("func")->empty());
104 }
105
106 TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) {
107   SmallString<1024> Mem;
108
109   LLVMContext Context;
110   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
111       Context, Mem, "define internal i32 @func() {\n"
112                       "ret i32 0\n"
113                     "}\n");
114
115   EXPECT_FALSE(verifyModule(*M, &dbgs()));
116
117   M->getFunction("func")->materialize();
118   EXPECT_FALSE(M->getFunction("func")->empty());
119   EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
120               GlobalValue::InternalLinkage);
121
122   // Check that the linkage type is preserved after dematerialization.
123   M->getFunction("func")->dematerialize();
124   EXPECT_TRUE(M->getFunction("func")->empty());
125   EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
126               GlobalValue::InternalLinkage);
127   EXPECT_FALSE(verifyModule(*M, &dbgs()));
128 }
129
130 // Tests that lazy evaluation can parse functions out of order.
131 TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
132   SmallString<1024> Mem;
133   LLVMContext Context;
134   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
135       Context, Mem, "define void @f() {\n"
136                     "  unreachable\n"
137                     "}\n"
138                     "define void @g() {\n"
139                     "  unreachable\n"
140                     "}\n"
141                     "define void @h() {\n"
142                     "  unreachable\n"
143                     "}\n"
144                     "define void @j() {\n"
145                     "  unreachable\n"
146                     "}\n");
147   EXPECT_FALSE(verifyModule(*M, &dbgs()));
148
149   Function *F = M->getFunction("f");
150   Function *G = M->getFunction("g");
151   Function *H = M->getFunction("h");
152   Function *J = M->getFunction("j");
153
154   // Initially all functions are not materialized (no basic blocks).
155   EXPECT_TRUE(F->empty());
156   EXPECT_TRUE(G->empty());
157   EXPECT_TRUE(H->empty());
158   EXPECT_TRUE(J->empty());
159   EXPECT_FALSE(verifyModule(*M, &dbgs()));
160
161   // Materialize h.
162   H->materialize();
163   EXPECT_TRUE(F->empty());
164   EXPECT_TRUE(G->empty());
165   EXPECT_FALSE(H->empty());
166   EXPECT_TRUE(J->empty());
167   EXPECT_FALSE(verifyModule(*M, &dbgs()));
168
169   // Materialize g.
170   G->materialize();
171   EXPECT_TRUE(F->empty());
172   EXPECT_FALSE(G->empty());
173   EXPECT_FALSE(H->empty());
174   EXPECT_TRUE(J->empty());
175   EXPECT_FALSE(verifyModule(*M, &dbgs()));
176
177   // Materialize j.
178   J->materialize();
179   EXPECT_TRUE(F->empty());
180   EXPECT_FALSE(G->empty());
181   EXPECT_FALSE(H->empty());
182   EXPECT_FALSE(J->empty());
183   EXPECT_FALSE(verifyModule(*M, &dbgs()));
184
185   // Materialize f.
186   F->materialize();
187   EXPECT_FALSE(F->empty());
188   EXPECT_FALSE(G->empty());
189   EXPECT_FALSE(H->empty());
190   EXPECT_FALSE(J->empty());
191   EXPECT_FALSE(verifyModule(*M, &dbgs()));
192 }
193
194 TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
195   SmallString<1024> Mem;
196
197   LLVMContext Context;
198   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
199       Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
200                     "define void @func() {\n"
201                     "  unreachable\n"
202                     "bb:\n"
203                     "  unreachable\n"
204                     "}\n");
205   EXPECT_FALSE(verifyModule(*M, &dbgs()));
206
207   // Try (and fail) to dematerialize @func.
208   M->getFunction("func")->dematerialize();
209   EXPECT_FALSE(M->getFunction("func")->empty());
210 }
211
212 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
213   SmallString<1024> Mem;
214
215   LLVMContext Context;
216   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
217       Context, Mem, "define i8* @before() {\n"
218                     "  ret i8* blockaddress(@func, %bb)\n"
219                     "}\n"
220                     "define void @other() {\n"
221                     "  unreachable\n"
222                     "}\n"
223                     "define void @func() {\n"
224                     "  unreachable\n"
225                     "bb:\n"
226                     "  unreachable\n"
227                     "}\n");
228   EXPECT_TRUE(M->getFunction("before")->empty());
229   EXPECT_TRUE(M->getFunction("func")->empty());
230   EXPECT_FALSE(verifyModule(*M, &dbgs()));
231
232   // Materialize @before, pulling in @func.
233   EXPECT_FALSE(M->getFunction("before")->materialize());
234   EXPECT_FALSE(M->getFunction("func")->empty());
235   EXPECT_TRUE(M->getFunction("other")->empty());
236   EXPECT_FALSE(verifyModule(*M, &dbgs()));
237
238   // Try (and fail) to dematerialize @func.
239   M->getFunction("func")->dematerialize();
240   EXPECT_FALSE(M->getFunction("func")->empty());
241   EXPECT_FALSE(verifyModule(*M, &dbgs()));
242 }
243
244 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
245   SmallString<1024> Mem;
246
247   LLVMContext Context;
248   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
249       Context, Mem, "define void @func() {\n"
250                     "  unreachable\n"
251                     "bb:\n"
252                     "  unreachable\n"
253                     "}\n"
254                     "define void @other() {\n"
255                     "  unreachable\n"
256                     "}\n"
257                     "define i8* @after() {\n"
258                     "  ret i8* blockaddress(@func, %bb)\n"
259                     "}\n");
260   EXPECT_TRUE(M->getFunction("after")->empty());
261   EXPECT_TRUE(M->getFunction("func")->empty());
262   EXPECT_FALSE(verifyModule(*M, &dbgs()));
263
264   // Materialize @after, pulling in @func.
265   EXPECT_FALSE(M->getFunction("after")->materialize());
266   EXPECT_FALSE(M->getFunction("func")->empty());
267   EXPECT_TRUE(M->getFunction("other")->empty());
268   EXPECT_FALSE(verifyModule(*M, &dbgs()));
269
270   // Try (and fail) to dematerialize @func.
271   M->getFunction("func")->dematerialize();
272   EXPECT_FALSE(M->getFunction("func")->empty());
273   EXPECT_FALSE(verifyModule(*M, &dbgs()));
274 }
275
276 } // end namespace