X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=unittests%2FBitcode%2FBitReaderTest.cpp;h=a27332b5b3550fee995d5bb1f63b4b9102b55981;hb=6d66a1cd2f6c47361bb9f294d7d2af1530f27914;hp=f33af2ff474f9bdf4fdf910bb17d3e03a14306bc;hpb=023d97d70305dfe5a1a24659496ef95dc6bf3d39;p=oota-llvm.git diff --git a/unittests/Bitcode/BitReaderTest.cpp b/unittests/Bitcode/BitReaderTest.cpp index f33af2ff474..a27332b5b35 100644 --- a/unittests/Bitcode/BitReaderTest.cpp +++ b/unittests/Bitcode/BitReaderTest.cpp @@ -8,58 +8,136 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/SmallString.h" -#include "llvm/Analysis/Verifier.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/AsmParser/Parser.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" -#include "llvm/PassManager.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" -namespace llvm { -namespace { - -static Module *makeLLVMModule() { - Module* Mod = new Module("test-mem", getGlobalContext()); +using namespace llvm; - FunctionType* FuncTy = - FunctionType::get(Type::getVoidTy(Mod->getContext()), false); - Function* Func = Function::Create(FuncTy,GlobalValue::ExternalLinkage, - "func", Mod); +namespace { - BasicBlock* Entry = BasicBlock::Create(Mod->getContext(), "entry", Func); - new UnreachableInst(Mod->getContext(), Entry); +std::unique_ptr parseAssembly(const char *Assembly) { + SMDiagnostic Error; + std::unique_ptr M = + parseAssemblyString(Assembly, Error, getGlobalContext()); - BasicBlock* BB = BasicBlock::Create(Mod->getContext(), "bb", Func); - new UnreachableInst(Mod->getContext(), BB); + std::string ErrMsg; + raw_string_ostream OS(ErrMsg); + Error.print("", OS); - PointerType* Int8Ptr = Type::getInt8PtrTy(Mod->getContext()); - new GlobalVariable(*Mod, Int8Ptr, /*isConstant=*/true, - GlobalValue::ExternalLinkage, - BlockAddress::get(BB), "table"); + // A failure here means that the test itself is buggy. + if (!M) + report_fatal_error(OS.str().c_str()); - return Mod; + return M; } -static void writeModuleToBuffer(SmallVectorImpl &Buffer) { - OwningPtr Mod(makeLLVMModule()); +static void writeModuleToBuffer(std::unique_ptr Mod, + SmallVectorImpl &Buffer) { raw_svector_ostream OS(Buffer); WriteBitcodeToFile(Mod.get(), OS); } +static std::unique_ptr getLazyModuleFromAssembly(LLVMContext &Context, + SmallString<1024> &Mem, + const char *Assembly) { + writeModuleToBuffer(parseAssembly(Assembly), Mem); + std::unique_ptr Buffer = + MemoryBuffer::getMemBuffer(Mem.str(), "test", false); + ErrorOr ModuleOrErr = + getLazyBitcodeModule(std::move(Buffer), Context); + return std::unique_ptr(ModuleOrErr.get()); +} + TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 SmallString<1024> Mem; - writeModuleToBuffer(Mem); - MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Mem.str(), "test", false); - std::string errMsg; - OwningPtr m(getLazyBitcodeModule(Buffer, getGlobalContext(), &errMsg)); - PassManager passes; - passes.add(createVerifierPass()); - passes.run(*m); + + LLVMContext Context; + std::unique_ptr M = getLazyModuleFromAssembly( + Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n" + "define void @func() {\n" + " unreachable\n" + "bb:\n" + " unreachable\n" + "}\n"); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Try (and fail) to dematerialize @func. + M->getFunction("func")->Dematerialize(); + EXPECT_FALSE(M->getFunction("func")->empty()); } +TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) { + SmallString<1024> Mem; + + LLVMContext Context; + std::unique_ptr M = getLazyModuleFromAssembly( + Context, Mem, "define i8* @before() {\n" + " ret i8* blockaddress(@func, %bb)\n" + "}\n" + "define void @other() {\n" + " unreachable\n" + "}\n" + "define void @func() {\n" + " unreachable\n" + "bb:\n" + " unreachable\n" + "}\n"); + EXPECT_TRUE(M->getFunction("before")->empty()); + EXPECT_TRUE(M->getFunction("func")->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Materialize @before, pulling in @func. + EXPECT_FALSE(M->getFunction("before")->Materialize()); + EXPECT_FALSE(M->getFunction("func")->empty()); + EXPECT_TRUE(M->getFunction("other")->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Try (and fail) to dematerialize @func. + M->getFunction("func")->Dematerialize(); + EXPECT_FALSE(M->getFunction("func")->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); } + +TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) { + SmallString<1024> Mem; + + LLVMContext Context; + std::unique_ptr M = getLazyModuleFromAssembly( + Context, Mem, "define void @func() {\n" + " unreachable\n" + "bb:\n" + " unreachable\n" + "}\n" + "define void @other() {\n" + " unreachable\n" + "}\n" + "define i8* @after() {\n" + " ret i8* blockaddress(@func, %bb)\n" + "}\n"); + EXPECT_TRUE(M->getFunction("after")->empty()); + EXPECT_TRUE(M->getFunction("func")->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Materialize @after, pulling in @func. + EXPECT_FALSE(M->getFunction("after")->Materialize()); + EXPECT_FALSE(M->getFunction("func")->empty()); + EXPECT_TRUE(M->getFunction("other")->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); + + // Try (and fail) to dematerialize @func. + M->getFunction("func")->Dematerialize(); + EXPECT_FALSE(M->getFunction("func")->empty()); + EXPECT_FALSE(verifyModule(*M, &dbgs())); } + +} // end namespace