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/ADT/STLExtras.h" 12 #include "llvm/AsmParser/Parser.h" 13 #include "llvm/Bitcode/BitstreamReader.h" 14 #include "llvm/Bitcode/BitstreamWriter.h" 15 #include "llvm/Bitcode/ReaderWriter.h" 16 #include "llvm/IR/Constants.h" 17 #include "llvm/IR/Instructions.h" 18 #include "llvm/IR/LLVMContext.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/IR/Verifier.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/Error.h" 23 #include "llvm/Support/MemoryBuffer.h" 24 #include "llvm/Support/SourceMgr.h" 25 #include "gtest/gtest.h" 26 27 using namespace llvm; 28 29 namespace { 30 31 std::unique_ptr<Module> parseAssembly(LLVMContext &Context, 32 const char *Assembly) { 33 SMDiagnostic Error; 34 std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context); 35 36 std::string ErrMsg; 37 raw_string_ostream OS(ErrMsg); 38 Error.print("", OS); 39 40 // A failure here means that the test itself is buggy. 41 if (!M) 42 report_fatal_error(OS.str().c_str()); 43 44 return M; 45 } 46 47 static void writeModuleToBuffer(std::unique_ptr<Module> Mod, 48 SmallVectorImpl<char> &Buffer) { 49 raw_svector_ostream OS(Buffer); 50 WriteBitcodeToFile(Mod.get(), OS); 51 } 52 53 static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context, 54 SmallString<1024> &Mem, 55 const char *Assembly) { 56 writeModuleToBuffer(parseAssembly(Context, Assembly), Mem); 57 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 58 getLazyBitcodeModule(MemoryBufferRef(Mem.str(), "test"), Context); 59 return std::move(ModuleOrErr.get()); 60 } 61 62 // Tests that lazy evaluation can parse functions out of order. 63 TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) { 64 SmallString<1024> Mem; 65 LLVMContext Context; 66 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 67 Context, Mem, "define void @f() {\n" 68 " unreachable\n" 69 "}\n" 70 "define void @g() {\n" 71 " unreachable\n" 72 "}\n" 73 "define void @h() {\n" 74 " unreachable\n" 75 "}\n" 76 "define void @j() {\n" 77 " unreachable\n" 78 "}\n"); 79 EXPECT_FALSE(verifyModule(*M, &dbgs())); 80 81 Function *F = M->getFunction("f"); 82 Function *G = M->getFunction("g"); 83 Function *H = M->getFunction("h"); 84 Function *J = M->getFunction("j"); 85 86 // Initially all functions are not materialized (no basic blocks). 87 EXPECT_TRUE(F->empty()); 88 EXPECT_TRUE(G->empty()); 89 EXPECT_TRUE(H->empty()); 90 EXPECT_TRUE(J->empty()); 91 EXPECT_FALSE(verifyModule(*M, &dbgs())); 92 93 // Materialize h. 94 ASSERT_FALSE(H->materialize()); 95 EXPECT_TRUE(F->empty()); 96 EXPECT_TRUE(G->empty()); 97 EXPECT_FALSE(H->empty()); 98 EXPECT_TRUE(J->empty()); 99 EXPECT_FALSE(verifyModule(*M, &dbgs())); 100 101 // Materialize g. 102 ASSERT_FALSE(G->materialize()); 103 EXPECT_TRUE(F->empty()); 104 EXPECT_FALSE(G->empty()); 105 EXPECT_FALSE(H->empty()); 106 EXPECT_TRUE(J->empty()); 107 EXPECT_FALSE(verifyModule(*M, &dbgs())); 108 109 // Materialize j. 110 ASSERT_FALSE(J->materialize()); 111 EXPECT_TRUE(F->empty()); 112 EXPECT_FALSE(G->empty()); 113 EXPECT_FALSE(H->empty()); 114 EXPECT_FALSE(J->empty()); 115 EXPECT_FALSE(verifyModule(*M, &dbgs())); 116 117 // Materialize f. 118 ASSERT_FALSE(F->materialize()); 119 EXPECT_FALSE(F->empty()); 120 EXPECT_FALSE(G->empty()); 121 EXPECT_FALSE(H->empty()); 122 EXPECT_FALSE(J->empty()); 123 EXPECT_FALSE(verifyModule(*M, &dbgs())); 124 } 125 126 TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 127 SmallString<1024> Mem; 128 129 LLVMContext Context; 130 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 131 Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n" 132 "define void @func() {\n" 133 " unreachable\n" 134 "bb:\n" 135 " unreachable\n" 136 "}\n"); 137 EXPECT_FALSE(verifyModule(*M, &dbgs())); 138 EXPECT_FALSE(M->getFunction("func")->empty()); 139 } 140 141 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) { 142 SmallString<1024> Mem; 143 144 LLVMContext Context; 145 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 146 Context, Mem, "define i8* @before() {\n" 147 " ret i8* blockaddress(@func, %bb)\n" 148 "}\n" 149 "define void @other() {\n" 150 " unreachable\n" 151 "}\n" 152 "define void @func() {\n" 153 " unreachable\n" 154 "bb:\n" 155 " unreachable\n" 156 "}\n"); 157 EXPECT_TRUE(M->getFunction("before")->empty()); 158 EXPECT_TRUE(M->getFunction("func")->empty()); 159 EXPECT_FALSE(verifyModule(*M, &dbgs())); 160 161 // Materialize @before, pulling in @func. 162 EXPECT_FALSE(M->getFunction("before")->materialize()); 163 EXPECT_FALSE(M->getFunction("func")->empty()); 164 EXPECT_TRUE(M->getFunction("other")->empty()); 165 EXPECT_FALSE(verifyModule(*M, &dbgs())); 166 } 167 168 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) { 169 SmallString<1024> Mem; 170 171 LLVMContext Context; 172 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 173 Context, Mem, "define void @func() {\n" 174 " unreachable\n" 175 "bb:\n" 176 " unreachable\n" 177 "}\n" 178 "define void @other() {\n" 179 " unreachable\n" 180 "}\n" 181 "define i8* @after() {\n" 182 " ret i8* blockaddress(@func, %bb)\n" 183 "}\n"); 184 EXPECT_TRUE(M->getFunction("after")->empty()); 185 EXPECT_TRUE(M->getFunction("func")->empty()); 186 EXPECT_FALSE(verifyModule(*M, &dbgs())); 187 188 // Materialize @after, pulling in @func. 189 EXPECT_FALSE(M->getFunction("after")->materialize()); 190 EXPECT_FALSE(M->getFunction("func")->empty()); 191 EXPECT_TRUE(M->getFunction("other")->empty()); 192 EXPECT_FALSE(verifyModule(*M, &dbgs())); 193 } 194 195 } // end namespace 196