blob: 3b4600718b531e493ddce879aaa3db6f592f55eb [file] [log] [blame]
Chandler Carruth972cc0d2012-01-02 09:19:48 +00001//===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
Rafael Espindola47f79bb2012-01-02 07:49:53 +00002//
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
Rafael Espindolacc625c92015-06-17 01:15:47 +000010#include "llvm/ADT/STLExtras.h"
Teresa Johnsona5479192016-11-11 05:34:58 +000011#include "llvm/ADT/SmallString.h"
Chandler Carruth1b279142015-01-14 11:23:27 +000012#include "llvm/AsmParser/Parser.h"
Teresa Johnsona5479192016-11-11 05:34:58 +000013#include "llvm/Bitcode/BitcodeReader.h"
14#include "llvm/Bitcode/BitcodeWriter.h"
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000015#include "llvm/IR/LLVMContext.h"
16#include "llvm/IR/Module.h"
Chandler Carruth56e13942014-01-13 09:26:24 +000017#include "llvm/IR/Verifier.h"
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000018#include "llvm/Support/Debug.h"
Peter Collingbourne76c218e2016-11-09 17:49:19 +000019#include "llvm/Support/Error.h"
Rafael Espindola47f79bb2012-01-02 07:49:53 +000020#include "llvm/Support/MemoryBuffer.h"
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000021#include "llvm/Support/SourceMgr.h"
Rafael Espindola47f79bb2012-01-02 07:49:53 +000022#include "gtest/gtest.h"
23
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000024using namespace llvm;
25
Rafael Espindola47f79bb2012-01-02 07:49:53 +000026namespace {
27
Mehdi Amini8be77072016-04-14 21:59:01 +000028std::unique_ptr<Module> parseAssembly(LLVMContext &Context,
29 const char *Assembly) {
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000030 SMDiagnostic Error;
Mehdi Amini8be77072016-04-14 21:59:01 +000031 std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
Rafael Espindola47f79bb2012-01-02 07:49:53 +000032
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000033 std::string ErrMsg;
34 raw_string_ostream OS(ErrMsg);
35 Error.print("", OS);
Rafael Espindola47f79bb2012-01-02 07:49:53 +000036
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000037 // A failure here means that the test itself is buggy.
Rafael Espindola9b29ff92014-08-19 16:58:54 +000038 if (!M)
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000039 report_fatal_error(OS.str().c_str());
Rafael Espindola47f79bb2012-01-02 07:49:53 +000040
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000041 return M;
Rafael Espindola47f79bb2012-01-02 07:49:53 +000042}
43
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000044static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
45 SmallVectorImpl<char> &Buffer) {
Daniel Dunbarfdc8f782012-02-29 20:30:56 +000046 raw_svector_ostream OS(Buffer);
Rafael Espindola06d62072018-02-14 19:11:32 +000047 WriteBitcodeToFile(*Mod, OS);
Rafael Espindola47f79bb2012-01-02 07:49:53 +000048}
49
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +000050static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
51 SmallString<1024> &Mem,
52 const char *Assembly) {
Mehdi Amini8be77072016-04-14 21:59:01 +000053 writeModuleToBuffer(parseAssembly(Context, Assembly), Mem);
Peter Collingbournedead0812016-11-13 07:00:17 +000054 Expected<std::unique_ptr<Module>> ModuleOrErr =
Peter Collingbourne5498e182016-11-08 06:03:43 +000055 getLazyBitcodeModule(MemoryBufferRef(Mem.str(), "test"), Context);
Peter Collingbournedead0812016-11-13 07:00:17 +000056 if (!ModuleOrErr)
57 report_fatal_error("Could not parse bitcode module");
Rafael Espindola20a67852015-06-16 22:27:55 +000058 return std::move(ModuleOrErr.get());
Rafael Espindola47f79bb2012-01-02 07:49:53 +000059}
Chandler Carruth972cc0d2012-01-02 09:19:48 +000060
Derek Schuff683cf0f2015-05-06 16:52:35 +000061// Tests that lazy evaluation can parse functions out of order.
62TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
63 SmallString<1024> Mem;
64 LLVMContext Context;
65 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
66 Context, Mem, "define void @f() {\n"
67 " unreachable\n"
68 "}\n"
69 "define void @g() {\n"
70 " unreachable\n"
71 "}\n"
72 "define void @h() {\n"
73 " unreachable\n"
74 "}\n"
75 "define void @j() {\n"
76 " unreachable\n"
77 "}\n");
78 EXPECT_FALSE(verifyModule(*M, &dbgs()));
79
80 Function *F = M->getFunction("f");
81 Function *G = M->getFunction("g");
82 Function *H = M->getFunction("h");
83 Function *J = M->getFunction("j");
84
85 // Initially all functions are not materialized (no basic blocks).
86 EXPECT_TRUE(F->empty());
87 EXPECT_TRUE(G->empty());
88 EXPECT_TRUE(H->empty());
89 EXPECT_TRUE(J->empty());
90 EXPECT_FALSE(verifyModule(*M, &dbgs()));
91
92 // Materialize h.
Peter Collingbourne76c218e2016-11-09 17:49:19 +000093 ASSERT_FALSE(H->materialize());
Derek Schuff683cf0f2015-05-06 16:52:35 +000094 EXPECT_TRUE(F->empty());
95 EXPECT_TRUE(G->empty());
96 EXPECT_FALSE(H->empty());
97 EXPECT_TRUE(J->empty());
98 EXPECT_FALSE(verifyModule(*M, &dbgs()));
99
100 // Materialize g.
Peter Collingbourne76c218e2016-11-09 17:49:19 +0000101 ASSERT_FALSE(G->materialize());
Derek Schuff683cf0f2015-05-06 16:52:35 +0000102 EXPECT_TRUE(F->empty());
103 EXPECT_FALSE(G->empty());
104 EXPECT_FALSE(H->empty());
105 EXPECT_TRUE(J->empty());
106 EXPECT_FALSE(verifyModule(*M, &dbgs()));
107
108 // Materialize j.
Peter Collingbourne76c218e2016-11-09 17:49:19 +0000109 ASSERT_FALSE(J->materialize());
Derek Schuff683cf0f2015-05-06 16:52:35 +0000110 EXPECT_TRUE(F->empty());
111 EXPECT_FALSE(G->empty());
112 EXPECT_FALSE(H->empty());
113 EXPECT_FALSE(J->empty());
114 EXPECT_FALSE(verifyModule(*M, &dbgs()));
115
116 // Materialize f.
Peter Collingbourne76c218e2016-11-09 17:49:19 +0000117 ASSERT_FALSE(F->materialize());
Derek Schuff683cf0f2015-05-06 16:52:35 +0000118 EXPECT_FALSE(F->empty());
119 EXPECT_FALSE(G->empty());
120 EXPECT_FALSE(H->empty());
121 EXPECT_FALSE(J->empty());
122 EXPECT_FALSE(verifyModule(*M, &dbgs()));
123}
124
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +0000125TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
126 SmallString<1024> Mem;
127
128 LLVMContext Context;
129 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
130 Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
131 "define void @func() {\n"
132 " unreachable\n"
133 "bb:\n"
134 " unreachable\n"
135 "}\n");
136 EXPECT_FALSE(verifyModule(*M, &dbgs()));
Peter Collingbournee8516582016-11-02 00:08:19 +0000137 EXPECT_FALSE(M->getFunction("func")->empty());
Duncan P. N. Exon Smithcf8b9592014-08-01 21:11:34 +0000138}
139
140TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
141 SmallString<1024> Mem;
142
143 LLVMContext Context;
144 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
145 Context, Mem, "define i8* @before() {\n"
146 " ret i8* blockaddress(@func, %bb)\n"
147 "}\n"
148 "define void @other() {\n"
149 " unreachable\n"
150 "}\n"
151 "define void @func() {\n"
152 " unreachable\n"
153 "bb:\n"
154 " unreachable\n"
155 "}\n");
156 EXPECT_TRUE(M->getFunction("before")->empty());
157 EXPECT_TRUE(M->getFunction("func")->empty());
158 EXPECT_FALSE(verifyModule(*M, &dbgs()));
159
160 // Materialize @before, pulling in @func.
Rafael Espindolac4982842014-10-24 22:50:48 +0000161 EXPECT_FALSE(M->getFunction("before")->materialize());
Duncan P. N. Exon Smithcf8b9592014-08-01 21:11:34 +0000162 EXPECT_FALSE(M->getFunction("func")->empty());
163 EXPECT_TRUE(M->getFunction("other")->empty());
164 EXPECT_FALSE(verifyModule(*M, &dbgs()));
Duncan P. N. Exon Smithcf8b9592014-08-01 21:11:34 +0000165}
166
167TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
168 SmallString<1024> Mem;
169
170 LLVMContext Context;
171 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
172 Context, Mem, "define void @func() {\n"
173 " unreachable\n"
174 "bb:\n"
175 " unreachable\n"
176 "}\n"
177 "define void @other() {\n"
178 " unreachable\n"
179 "}\n"
180 "define i8* @after() {\n"
181 " ret i8* blockaddress(@func, %bb)\n"
182 "}\n");
183 EXPECT_TRUE(M->getFunction("after")->empty());
184 EXPECT_TRUE(M->getFunction("func")->empty());
185 EXPECT_FALSE(verifyModule(*M, &dbgs()));
186
187 // Materialize @after, pulling in @func.
Rafael Espindolac4982842014-10-24 22:50:48 +0000188 EXPECT_FALSE(M->getFunction("after")->materialize());
Duncan P. N. Exon Smithcf8b9592014-08-01 21:11:34 +0000189 EXPECT_FALSE(M->getFunction("func")->empty());
190 EXPECT_TRUE(M->getFunction("other")->empty());
191 EXPECT_FALSE(verifyModule(*M, &dbgs()));
Rafael Espindola47f79bb2012-01-02 07:49:53 +0000192}
Duncan P. N. Exon Smith2e9b60a2014-08-01 21:01:04 +0000193
194} // end namespace