blob: 8331527437b54f899908eef857e4e8cde307a817 [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
Daniel Dunbar5fa5ecf2012-02-29 20:30:56 +000010#include "llvm/ADT/SmallString.h"
Rafael Espindolab7993462012-01-02 07:49:53 +000011#include "llvm/Bitcode/BitstreamWriter.h"
12#include "llvm/Bitcode/ReaderWriter.h"
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000013#include "llvm/AsmParser/Parser.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000014#include "llvm/IR/Constants.h"
15#include "llvm/IR/Instructions.h"
16#include "llvm/IR/LLVMContext.h"
17#include "llvm/IR/Module.h"
Chandler Carruth5ad5f152014-01-13 09:26:24 +000018#include "llvm/IR/Verifier.h"
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000019#include "llvm/Support/Debug.h"
Rafael Espindolab7993462012-01-02 07:49:53 +000020#include "llvm/Support/MemoryBuffer.h"
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000021#include "llvm/Support/SourceMgr.h"
Rafael Espindolab7993462012-01-02 07:49:53 +000022#include "gtest/gtest.h"
23
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000024using namespace llvm;
25
Rafael Espindolab7993462012-01-02 07:49:53 +000026namespace {
27
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000028std::unique_ptr<Module> parseAssembly(const char *Assembly) {
29 auto M = make_unique<Module>("Module", getGlobalContext());
Rafael Espindolab7993462012-01-02 07:49:53 +000030
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000031 SMDiagnostic Error;
32 bool Parsed =
33 ParseAssemblyString(Assembly, M.get(), Error, M->getContext()) == M.get();
Rafael Espindolab7993462012-01-02 07:49:53 +000034
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000035 std::string ErrMsg;
36 raw_string_ostream OS(ErrMsg);
37 Error.print("", OS);
Rafael Espindolab7993462012-01-02 07:49:53 +000038
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000039 // A failure here means that the test itself is buggy.
40 if (!Parsed)
41 report_fatal_error(OS.str().c_str());
Rafael Espindolab7993462012-01-02 07:49:53 +000042
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000043 return M;
Rafael Espindolab7993462012-01-02 07:49:53 +000044}
45
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000046static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
47 SmallVectorImpl<char> &Buffer) {
Daniel Dunbar5fa5ecf2012-02-29 20:30:56 +000048 raw_svector_ostream OS(Buffer);
NAKAMURA Takumi508baf72013-01-23 08:33:13 +000049 WriteBitcodeToFile(Mod.get(), OS);
Rafael Espindolab7993462012-01-02 07:49:53 +000050}
51
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000052static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
53 SmallString<1024> &Mem,
54 const char *Assembly) {
55 writeModuleToBuffer(parseAssembly(Assembly), Mem);
Daniel Dunbar5fa5ecf2012-02-29 20:30:56 +000056 MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000057 ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModule(Buffer, Context);
58 return std::unique_ptr<Module>(ModuleOrErr.get());
Rafael Espindolab7993462012-01-02 07:49:53 +000059}
Chandler Carruthe5172732012-01-02 09:19:48 +000060
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +000061TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
62 SmallString<1024> Mem;
63
64 LLVMContext Context;
65 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
66 Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
67 "define void @func() {\n"
68 " unreachable\n"
69 "bb:\n"
70 " unreachable\n"
71 "}\n");
72 EXPECT_FALSE(verifyModule(*M, &dbgs()));
Duncan P. N. Exon Smith908d8092014-08-01 21:11:34 +000073
74 // Try (and fail) to dematerialize @func.
75 M->getFunction("func")->Dematerialize();
76 EXPECT_FALSE(M->getFunction("func")->empty());
77}
78
79TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
80 SmallString<1024> Mem;
81
82 LLVMContext Context;
83 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
84 Context, Mem, "define i8* @before() {\n"
85 " ret i8* blockaddress(@func, %bb)\n"
86 "}\n"
87 "define void @other() {\n"
88 " unreachable\n"
89 "}\n"
90 "define void @func() {\n"
91 " unreachable\n"
92 "bb:\n"
93 " unreachable\n"
94 "}\n");
95 EXPECT_TRUE(M->getFunction("before")->empty());
96 EXPECT_TRUE(M->getFunction("func")->empty());
97 EXPECT_FALSE(verifyModule(*M, &dbgs()));
98
99 // Materialize @before, pulling in @func.
100 EXPECT_FALSE(M->getFunction("before")->Materialize());
101 EXPECT_FALSE(M->getFunction("func")->empty());
102 EXPECT_TRUE(M->getFunction("other")->empty());
103 EXPECT_FALSE(verifyModule(*M, &dbgs()));
104
105 // Try (and fail) to dematerialize @func.
106 M->getFunction("func")->Dematerialize();
107 EXPECT_FALSE(M->getFunction("func")->empty());
108 EXPECT_FALSE(verifyModule(*M, &dbgs()));
109}
110
111TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
112 SmallString<1024> Mem;
113
114 LLVMContext Context;
115 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
116 Context, Mem, "define void @func() {\n"
117 " unreachable\n"
118 "bb:\n"
119 " unreachable\n"
120 "}\n"
121 "define void @other() {\n"
122 " unreachable\n"
123 "}\n"
124 "define i8* @after() {\n"
125 " ret i8* blockaddress(@func, %bb)\n"
126 "}\n");
127 EXPECT_TRUE(M->getFunction("after")->empty());
128 EXPECT_TRUE(M->getFunction("func")->empty());
129 EXPECT_FALSE(verifyModule(*M, &dbgs()));
130
131 // Materialize @after, pulling in @func.
132 EXPECT_FALSE(M->getFunction("after")->Materialize());
133 EXPECT_FALSE(M->getFunction("func")->empty());
134 EXPECT_TRUE(M->getFunction("other")->empty());
135 EXPECT_FALSE(verifyModule(*M, &dbgs()));
136
137 // Try (and fail) to dematerialize @func.
138 M->getFunction("func")->Dematerialize();
139 EXPECT_FALSE(M->getFunction("func")->empty());
140 EXPECT_FALSE(verifyModule(*M, &dbgs()));
Rafael Espindolab7993462012-01-02 07:49:53 +0000141}
Duncan P. N. Exon Smith7a2990c2014-08-01 21:01:04 +0000142
143} // end namespace