]> git.proxmox.com Git - rustc.git/blob - src/llvm/unittests/Bitcode/BitReaderTest.cpp
Imported Upstream version 1.0.0+dfsg1
[rustc.git] / src / llvm / 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/AsmParser/Parser.h"
12 #include "llvm/Bitcode/BitstreamWriter.h"
13 #include "llvm/Bitcode/ReaderWriter.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/Verifier.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "gtest/gtest.h"
23
24 using namespace llvm;
25
26 namespace {
27
28 std::unique_ptr<Module> parseAssembly(const char *Assembly) {
29 SMDiagnostic Error;
30 std::unique_ptr<Module> M =
31 parseAssemblyString(Assembly, Error, getGlobalContext());
32
33 std::string ErrMsg;
34 raw_string_ostream OS(ErrMsg);
35 Error.print("", OS);
36
37 // A failure here means that the test itself is buggy.
38 if (!M)
39 report_fatal_error(OS.str().c_str());
40
41 return M;
42 }
43
44 static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
45 SmallVectorImpl<char> &Buffer) {
46 raw_svector_ostream OS(Buffer);
47 WriteBitcodeToFile(Mod.get(), OS);
48 }
49
50 static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
51 SmallString<1024> &Mem,
52 const char *Assembly) {
53 writeModuleToBuffer(parseAssembly(Assembly), Mem);
54 std::unique_ptr<MemoryBuffer> Buffer =
55 MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
56 ErrorOr<Module *> ModuleOrErr =
57 getLazyBitcodeModule(std::move(Buffer), Context);
58 return std::unique_ptr<Module>(ModuleOrErr.get());
59 }
60
61 TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) {
62 SmallString<1024> Mem;
63
64 LLVMContext Context;
65 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
66 Context, Mem, "define internal i32 @func() {\n"
67 "ret i32 0\n"
68 "}\n");
69
70 EXPECT_FALSE(verifyModule(*M, &dbgs()));
71
72 M->getFunction("func")->materialize();
73 EXPECT_FALSE(M->getFunction("func")->empty());
74 EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
75 GlobalValue::InternalLinkage);
76
77 // Check that the linkage type is preserved after dematerialization.
78 M->getFunction("func")->Dematerialize();
79 EXPECT_TRUE(M->getFunction("func")->empty());
80 EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
81 GlobalValue::InternalLinkage);
82 EXPECT_FALSE(verifyModule(*M, &dbgs()));
83 }
84
85 TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
86 SmallString<1024> Mem;
87
88 LLVMContext Context;
89 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
90 Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
91 "define void @func() {\n"
92 " unreachable\n"
93 "bb:\n"
94 " unreachable\n"
95 "}\n");
96 EXPECT_FALSE(verifyModule(*M, &dbgs()));
97
98 // Try (and fail) to dematerialize @func.
99 M->getFunction("func")->Dematerialize();
100 EXPECT_FALSE(M->getFunction("func")->empty());
101 }
102
103 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
104 SmallString<1024> Mem;
105
106 LLVMContext Context;
107 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
108 Context, Mem, "define i8* @before() {\n"
109 " ret i8* blockaddress(@func, %bb)\n"
110 "}\n"
111 "define void @other() {\n"
112 " unreachable\n"
113 "}\n"
114 "define void @func() {\n"
115 " unreachable\n"
116 "bb:\n"
117 " unreachable\n"
118 "}\n");
119 EXPECT_TRUE(M->getFunction("before")->empty());
120 EXPECT_TRUE(M->getFunction("func")->empty());
121 EXPECT_FALSE(verifyModule(*M, &dbgs()));
122
123 // Materialize @before, pulling in @func.
124 EXPECT_FALSE(M->getFunction("before")->materialize());
125 EXPECT_FALSE(M->getFunction("func")->empty());
126 EXPECT_TRUE(M->getFunction("other")->empty());
127 EXPECT_FALSE(verifyModule(*M, &dbgs()));
128
129 // Try (and fail) to dematerialize @func.
130 M->getFunction("func")->Dematerialize();
131 EXPECT_FALSE(M->getFunction("func")->empty());
132 EXPECT_FALSE(verifyModule(*M, &dbgs()));
133 }
134
135 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
136 SmallString<1024> Mem;
137
138 LLVMContext Context;
139 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
140 Context, Mem, "define void @func() {\n"
141 " unreachable\n"
142 "bb:\n"
143 " unreachable\n"
144 "}\n"
145 "define void @other() {\n"
146 " unreachable\n"
147 "}\n"
148 "define i8* @after() {\n"
149 " ret i8* blockaddress(@func, %bb)\n"
150 "}\n");
151 EXPECT_TRUE(M->getFunction("after")->empty());
152 EXPECT_TRUE(M->getFunction("func")->empty());
153 EXPECT_FALSE(verifyModule(*M, &dbgs()));
154
155 // Materialize @after, pulling in @func.
156 EXPECT_FALSE(M->getFunction("after")->materialize());
157 EXPECT_FALSE(M->getFunction("func")->empty());
158 EXPECT_TRUE(M->getFunction("other")->empty());
159 EXPECT_FALSE(verifyModule(*M, &dbgs()));
160
161 // Try (and fail) to dematerialize @func.
162 M->getFunction("func")->Dematerialize();
163 EXPECT_FALSE(M->getFunction("func")->empty());
164 EXPECT_FALSE(verifyModule(*M, &dbgs()));
165 }
166
167 } // end namespace