[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
This commit is contained in:
Eli Friedman 2020-05-13 11:44:03 -07:00
parent 6a3469f58d
commit 44ecaabc07
1 changed files with 24 additions and 5 deletions

View File

@ -3428,6 +3428,22 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
SmallVector<uint64_t, 64> 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<llvm::BitstreamEntry> 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);
}
}