From 44ecaabc0729fb75fcfec1d46a6bef6bc7c9e1e1 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 13 May 2020 11:44:03 -0700 Subject: [BitcodeReader] datalayout must be specified before it is queried. This isn't really a new invariant; it effectively already existed due to existing DataLayout queries. But this makes it explicit. This is technically not backward-compatible with the existing bitcode reader, but it's backward-compatible with the output of the bitcode writer, which is what matters in practice. No testcase because I don't know a good way to write one: there are no existing tools that can generate a bitcode file that would trigger the error. Split off from D78403. Differential Revision: https://reviews.llvm.org/D79900 --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp') diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 6e9ff6e..9e5f0e0 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3428,6 +3428,22 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, SmallVector Record; + // Parts of bitcode parsing depend on the datalayout. Make sure we + // finalize the datalayout before we run any of that code. + bool ResolvedDataLayout = false; + auto ResolveDataLayout = [&] { + if (ResolvedDataLayout) + return; + + // datalayout and triple can't be parsed after this point. + ResolvedDataLayout = true; + + // Upgrade data layout string. + std::string DL = llvm::UpgradeDataLayoutString( + TheModule->getDataLayoutStr(), TheModule->getTargetTriple()); + TheModule->setDataLayout(DL); + }; + // Read all the records for this module. while (true) { Expected MaybeEntry = Stream.advance(); @@ -3439,6 +3455,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, case BitstreamEntry::Error: return error("Malformed block"); case BitstreamEntry::EndBlock: + ResolveDataLayout(); return globalCleanup(); case BitstreamEntry::SubBlock: @@ -3503,6 +3520,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, return Err; break; case bitc::FUNCTION_BLOCK_ID: + ResolveDataLayout(); + // If this is the first function body we've seen, reverse the // FunctionsWithBodies list. if (!SeenFirstFunctionBody) { @@ -3589,6 +3608,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, break; } case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] + if (ResolvedDataLayout) + return error("target triple too late in module"); std::string S; if (convertToString(Record, 0, S)) return error("Invalid record"); @@ -3596,6 +3617,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, break; } case bitc::MODULE_CODE_DATALAYOUT: { // DATALAYOUT: [strchr x N] + if (ResolvedDataLayout) + return error("datalayout too late in module"); std::string S; if (convertToString(Record, 0, S)) return error("Invalid record"); @@ -3640,6 +3663,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, return Err; break; case bitc::MODULE_CODE_FUNCTION: + ResolveDataLayout(); if (Error Err = parseFunctionRecord(Record)) return Err; break; @@ -3667,11 +3691,6 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, break; } Record.clear(); - - // Upgrade data layout string. - std::string DL = llvm::UpgradeDataLayoutString( - TheModule->getDataLayoutStr(), TheModule->getTargetTriple()); - TheModule->setDataLayout(DL); } } -- cgit v1.1