|
10 | 10 | #include "llvm/ADT/SmallString.h"
|
11 | 11 | #include "llvm/Bitcode/BitstreamWriter.h"
|
12 | 12 | #include "llvm/Bitcode/ReaderWriter.h"
|
| 13 | +#include "llvm/AsmParser/Parser.h" |
13 | 14 | #include "llvm/IR/Constants.h"
|
14 | 15 | #include "llvm/IR/Instructions.h"
|
15 | 16 | #include "llvm/IR/LLVMContext.h"
|
16 | 17 | #include "llvm/IR/Module.h"
|
17 | 18 | #include "llvm/IR/Verifier.h"
|
18 |
| -#include "llvm/PassManager.h" |
| 19 | +#include "llvm/Support/Debug.h" |
19 | 20 | #include "llvm/Support/MemoryBuffer.h"
|
| 21 | +#include "llvm/Support/SourceMgr.h" |
20 | 22 | #include "gtest/gtest.h"
|
21 | 23 |
|
22 |
| -namespace llvm { |
23 |
| -namespace { |
| 24 | +using namespace llvm; |
24 | 25 |
|
25 |
| -static Module *makeLLVMModule() { |
26 |
| - Module* Mod = new Module("test-mem", getGlobalContext()); |
| 26 | +namespace { |
27 | 27 |
|
28 |
| - FunctionType* FuncTy = |
29 |
| - FunctionType::get(Type::getVoidTy(Mod->getContext()), false); |
30 |
| - Function* Func = Function::Create(FuncTy,GlobalValue::ExternalLinkage, |
31 |
| - "func", Mod); |
| 28 | +std::unique_ptr<Module> parseAssembly(const char *Assembly) { |
| 29 | + auto M = make_unique<Module>("Module", getGlobalContext()); |
32 | 30 |
|
33 |
| - BasicBlock* Entry = BasicBlock::Create(Mod->getContext(), "entry", Func); |
34 |
| - new UnreachableInst(Mod->getContext(), Entry); |
| 31 | + SMDiagnostic Error; |
| 32 | + bool Parsed = |
| 33 | + ParseAssemblyString(Assembly, M.get(), Error, M->getContext()) == M.get(); |
35 | 34 |
|
36 |
| - BasicBlock* BB = BasicBlock::Create(Mod->getContext(), "bb", Func); |
37 |
| - new UnreachableInst(Mod->getContext(), BB); |
| 35 | + std::string ErrMsg; |
| 36 | + raw_string_ostream OS(ErrMsg); |
| 37 | + Error.print("", OS); |
38 | 38 |
|
39 |
| - PointerType* Int8Ptr = Type::getInt8PtrTy(Mod->getContext()); |
40 |
| - new GlobalVariable(*Mod, Int8Ptr, /*isConstant=*/true, |
41 |
| - GlobalValue::ExternalLinkage, |
42 |
| - BlockAddress::get(BB), "table"); |
| 39 | + // A failure here means that the test itself is buggy. |
| 40 | + if (!Parsed) |
| 41 | + report_fatal_error(OS.str().c_str()); |
43 | 42 |
|
44 |
| - return Mod; |
| 43 | + return M; |
45 | 44 | }
|
46 | 45 |
|
47 |
| -static void writeModuleToBuffer(SmallVectorImpl<char> &Buffer) { |
48 |
| - std::unique_ptr<Module> Mod(makeLLVMModule()); |
| 46 | +static void writeModuleToBuffer(std::unique_ptr<Module> Mod, |
| 47 | + SmallVectorImpl<char> &Buffer) { |
49 | 48 | raw_svector_ostream OS(Buffer);
|
50 | 49 | WriteBitcodeToFile(Mod.get(), OS);
|
51 | 50 | }
|
52 | 51 |
|
53 |
| -TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 |
54 |
| - SmallString<1024> Mem; |
55 |
| - writeModuleToBuffer(Mem); |
| 52 | +static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context, |
| 53 | + SmallString<1024> &Mem, |
| 54 | + const char *Assembly) { |
| 55 | + writeModuleToBuffer(parseAssembly(Assembly), Mem); |
56 | 56 | MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
|
57 |
| - ErrorOr<Module *> ModuleOrErr = |
58 |
| - getLazyBitcodeModule(Buffer, getGlobalContext()); |
59 |
| - std::unique_ptr<Module> m(ModuleOrErr.get()); |
60 |
| - PassManager passes; |
61 |
| - passes.add(createVerifierPass()); |
62 |
| - passes.add(createDebugInfoVerifierPass()); |
63 |
| - passes.run(*m); |
| 57 | + ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModule(Buffer, Context); |
| 58 | + return std::unique_ptr<Module>(ModuleOrErr.get()); |
64 | 59 | }
|
65 | 60 |
|
| 61 | +TEST(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())); |
66 | 73 | }
|
67 |
| -} |
| 74 | + |
| 75 | +} // end namespace |
0 commit comments