blob: 0003a2b6fb8f952a17f3139826fa2b83229c751d [file] [log] [blame]
Chandler Carruthe5172732012-01-02 09:19:48 +00001//===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
Rafael Espindolab7993462012-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 Espindola456baad2015-06-17 01:15:47 +000010#include "llvm/ADT/STLExtras.h"
Teresa Johnsonad176792016-11-11 05:34:58 +000011#include "llvm/ADT/SmallString.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000012#include "llvm/AsmParser/Parser.h"
Teresa Johnsonad176792016-11-11 05:34:58 +000013#include "llvm/Bitcode/BitcodeReader.h"
14#include "llvm/Bitcode/BitcodeWriter.h"
Derek Schuffb4c1c282015-08-03 18:01:50 +000015#include "llvm/Bitcode/BitstreamReader.h"
Rafael Espindolab7993462012-01-02 07:49:53 +000016#include "llvm/Bitcode/BitstreamWriter.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000017#include "llvm/IR/Constants.h"
18#include "llvm/IR/Instructions.h"
19#include "llvm/IR/LLVMContext.h"
20#include "llvm/IR/Module.h"
Chandler Carruth5ad5f152014-01-13 09:26:24 +000021#include "llvm/IR/Verifier.h"
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000022#include "llvm/Support/Debug.h"
Peter Collingbourne7f00d0a2016-11-09 17:49:19 +000023#include "llvm/Support/Error.h"
Rafael Espindolab7993462012-01-02 07:49:53 +000024#include "llvm/Support/MemoryBuffer.h"
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000025#include "llvm/Support/SourceMgr.h"
Rafael Espindolab7993462012-01-02 07:49:53 +000026#include "gtest/gtest.h"
27
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000028using namespace llvm;
29
Rafael Espindolab7993462012-01-02 07:49:53 +000030namespace {
31
Mehdi Amini03b42e42016-04-14 21:59:01 +000032std::unique_ptr<Module> parseAssembly(LLVMContext &Context,
33 const char *Assembly) {
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000034 SMDiagnostic Error;
Mehdi Amini03b42e42016-04-14 21:59:01 +000035 std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
Rafael Espindolab7993462012-01-02 07:49:53 +000036
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000037 std::string ErrMsg;
38 raw_string_ostream OS(ErrMsg);
39 Error.print("", OS);
Rafael Espindolab7993462012-01-02 07:49:53 +000040
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000041 // A failure here means that the test itself is buggy.
Rafael Espindola11c07d72014-08-19 16:58:54 +000042 if (!M)
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000043 report_fatal_error(OS.str().c_str());
Rafael Espindolab7993462012-01-02 07:49:53 +000044
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000045 return M;
Rafael Espindolab7993462012-01-02 07:49:53 +000046}
47
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000048static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
49 SmallVectorImpl<char> &Buffer) {
Daniel Dunbar5fa5ecf2012-02-29 20:30:56 +000050 raw_svector_ostream OS(Buffer);
NAKAMURA Takumi508baf72013-01-23 08:33:13 +000051 WriteBitcodeToFile(Mod.get(), OS);
Rafael Espindolab7993462012-01-02 07:49:53 +000052}
53
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000054static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
55 SmallString<1024> &Mem,
56 const char *Assembly) {
Mehdi Amini03b42e42016-04-14 21:59:01 +000057 writeModuleToBuffer(parseAssembly(Context, Assembly), Mem);
Peter Collingbourned9445c42016-11-13 07:00:17 +000058 Expected<std::unique_ptr<Module>> ModuleOrErr =
Peter Collingbournee2dcf7c2016-11-08 06:03:43 +000059 getLazyBitcodeModule(MemoryBufferRef(Mem.str(), "test"), Context);
Peter Collingbourned9445c42016-11-13 07:00:17 +000060 if (!ModuleOrErr)
61 report_fatal_error("Could not parse bitcode module");
Rafael Espindoladcd1dca2015-06-16 22:27:55 +000062 return std::move(ModuleOrErr.get());
Rafael Espindolab7993462012-01-02 07:49:53 +000063}
Chandler Carruthe5172732012-01-02 09:19:48 +000064
Derek Schuff5d8dfd32015-05-06 16:52:35 +000065// Tests that lazy evaluation can parse functions out of order.
66TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
67 SmallString<1024> Mem;
68 LLVMContext Context;
69 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
70 Context, Mem, "define void @f() {\n"
71 " unreachable\n"
72 "}\n"
73 "define void @g() {\n"
74 " unreachable\n"
75 "}\n"
76 "define void @h() {\n"
77 " unreachable\n"
78 "}\n"
79 "define void @j() {\n"
80 " unreachable\n"
81 "}\n");
82 EXPECT_FALSE(verifyModule(*M, &dbgs()));
83
84 Function *F = M->getFunction("f");
85 Function *G = M->getFunction("g");
86 Function *H = M->getFunction("h");
87 Function *J = M->getFunction("j");
88
89 // Initially all functions are not materialized (no basic blocks).
90 EXPECT_TRUE(F->empty());
91 EXPECT_TRUE(G->empty());
92 EXPECT_TRUE(H->empty());
93 EXPECT_TRUE(J->empty());
94 EXPECT_FALSE(verifyModule(*M, &dbgs()));
95
96 // Materialize h.
Peter Collingbourne7f00d0a2016-11-09 17:49:19 +000097 ASSERT_FALSE(H->materialize());
Derek Schuff5d8dfd32015-05-06 16:52:35 +000098 EXPECT_TRUE(F->empty());
99 EXPECT_TRUE(G->empty());
100 EXPECT_FALSE(H->empty());
101 EXPECT_TRUE(J->empty());
102 EXPECT_FALSE(verifyModule(*M, &dbgs()));
103
104 // Materialize g.
Peter Collingbourne7f00d0a2016-11-09 17:49:19 +0000105 ASSERT_FALSE(G->materialize());
Derek Schuff5d8dfd32015-05-06 16:52:35 +0000106 EXPECT_TRUE(F->empty());
107 EXPECT_FALSE(G->empty());
108 EXPECT_FALSE(H->empty());
109 EXPECT_TRUE(J->empty());
110 EXPECT_FALSE(verifyModule(*M, &dbgs()));
111
112 // Materialize j.
Peter Collingbourne7f00d0a2016-11-09 17:49:19 +0000113 ASSERT_FALSE(J->materialize());
Derek Schuff5d8dfd32015-05-06 16:52:35 +0000114 EXPECT_TRUE(F->empty());
115 EXPECT_FALSE(G->empty());
116 EXPECT_FALSE(H->empty());
117 EXPECT_FALSE(J->empty());
118 EXPECT_FALSE(verifyModule(*M, &dbgs()));
119
120 // Materialize f.
Peter Collingbourne7f00d0a2016-11-09 17:49:19 +0000121 ASSERT_FALSE(F->materialize());
Derek Schuff5d8dfd32015-05-06 16:52:35 +0000122 EXPECT_FALSE(F->empty());
123 EXPECT_FALSE(G->empty());
124 EXPECT_FALSE(H->empty());
125 EXPECT_FALSE(J->empty());
126 EXPECT_FALSE(verifyModule(*M, &dbgs()));
127}
128
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +0000129TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
130 SmallString<1024> Mem;
131
132 LLVMContext Context;
133 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
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(verifyModule(*M, &dbgs()));
Peter Collingbourne028eb5a2016-11-02 00:08:19 +0000141 EXPECT_FALSE(M->getFunction("func")->empty());
Duncan P. N. Exon Smith908d8092014-08-01 21:11:34 +0000142}
143
144TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
145 SmallString<1024> Mem;
146
147 LLVMContext Context;
148 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
149 Context, Mem, "define i8* @before() {\n"
150 " ret i8* blockaddress(@func, %bb)\n"
151 "}\n"
152 "define void @other() {\n"
153 " unreachable\n"
154 "}\n"
155 "define void @func() {\n"
156 " unreachable\n"
157 "bb:\n"
158 " unreachable\n"
159 "}\n");
160 EXPECT_TRUE(M->getFunction("before")->empty());
161 EXPECT_TRUE(M->getFunction("func")->empty());
162 EXPECT_FALSE(verifyModule(*M, &dbgs()));
163
164 // Materialize @before, pulling in @func.
Rafael Espindola5a52e6d2014-10-24 22:50:48 +0000165 EXPECT_FALSE(M->getFunction("before")->materialize());
Duncan P. N. Exon Smith908d8092014-08-01 21:11:34 +0000166 EXPECT_FALSE(M->getFunction("func")->empty());
167 EXPECT_TRUE(M->getFunction("other")->empty());
168 EXPECT_FALSE(verifyModule(*M, &dbgs()));
Duncan P. N. Exon Smith908d8092014-08-01 21:11:34 +0000169}
170
171TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
172 SmallString<1024> Mem;
173
174 LLVMContext Context;
175 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
176 Context, Mem, "define void @func() {\n"
177 " unreachable\n"
178 "bb:\n"
179 " unreachable\n"
180 "}\n"
181 "define void @other() {\n"
182 " unreachable\n"
183 "}\n"
184 "define i8* @after() {\n"
185 " ret i8* blockaddress(@func, %bb)\n"
186 "}\n");
187 EXPECT_TRUE(M->getFunction("after")->empty());
188 EXPECT_TRUE(M->getFunction("func")->empty());
189 EXPECT_FALSE(verifyModule(*M, &dbgs()));
190
191 // Materialize @after, pulling in @func.
Rafael Espindola5a52e6d2014-10-24 22:50:48 +0000192 EXPECT_FALSE(M->getFunction("after")->materialize());
Duncan P. N. Exon Smith908d8092014-08-01 21:11:34 +0000193 EXPECT_FALSE(M->getFunction("func")->empty());
194 EXPECT_TRUE(M->getFunction("other")->empty());
195 EXPECT_FALSE(verifyModule(*M, &dbgs()));
Rafael Espindolab7993462012-01-02 07:49:53 +0000196}
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +0000197
198} // end namespace