From e6b649c5dfb19fa465ff5f4bcd10a5fa76bb50e2 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 6 May 2016 22:53:06 +0000 Subject: [PATCH] Implement a safer bitcode upgrade for DISubprogram. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bitcode upgrade I added for DISubprogram in r266446 was based on the assumption that the CU node for the subprogram was already materialized by the time the DISubprogram is visited. This assumption may not hold true as future versions of LLVM may decide to write out bitcode in a different order. This patch corrects this by introducing a versioning bit next to the distinct flag to unambiguously differentiate the new from the old record layouts. Note for people stabilizing LLVM out-of-tree: This patch introduces a bitcode incompatibility with llvm trunk revisions from r266446 — this commit. (But D19987 will ensure that it degrades gracefully). http://reviews.llvm.org/D20004 rdar://problem/26074194 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268816 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 12 +++++++----- lib/Bitcode/Writer/BitcodeWriter.cpp | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 11ddd013516..f3bd5508aa0 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2472,28 +2472,30 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { return error("Invalid record"); IsDistinct = - Record[0] || Record[8]; // All definitions should be distinct. + (Record[0] & 1) || Record[8]; // All definitions should be distinct. // Version 1 has a Function as Record[15]. // Version 2 has removed Record[15]. // Version 3 has the Unit as Record[15]. + bool HasUnit = Record[0] >= 2; + if (HasUnit && Record.size() != 19) + return error("Invalid record"); Metadata *CUorFn = getMDOrNull(Record[15]); unsigned Offset = Record.size() == 19 ? 1 : 0; - bool HasFn = Offset && dyn_cast_or_null(CUorFn); - bool HasCU = Offset && !HasFn; + bool HasFn = Offset && !HasUnit; DISubprogram *SP = GET_OR_DISTINCT( DISubprogram, (Context, getDITypeRefOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getMDOrNull(Record[6]), Record[7], Record[8], Record[9], getDITypeRefOrNull(Record[10]), Record[11], Record[12], Record[13], - Record[14], HasCU ? CUorFn : nullptr, + Record[14], HasUnit ? CUorFn : nullptr, getMDOrNull(Record[15 + Offset]), getMDOrNull(Record[16 + Offset]), getMDOrNull(Record[17 + Offset]))); MetadataList.assignValue(SP, NextMetadataNo++); // Upgrade sp->function mapping to function->sp mapping. if (HasFn) { - if (auto *CMD = dyn_cast(CUorFn)) + if (auto *CMD = dyn_cast_or_null(CUorFn)) if (auto *F = dyn_cast(CMD->getValue())) { if (F->isMaterializable()) // Defer until materialized; unmaterialized functions may not have diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 82e2cab6056..035e03e206e 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1353,7 +1353,8 @@ void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N, void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N, SmallVectorImpl &Record, unsigned Abbrev) { - Record.push_back(N->isDistinct()); + uint64_t HasUnitFlag = 1 << 1; + Record.push_back(N->isDistinct() | HasUnitFlag); Record.push_back(VE.getMetadataOrNullID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName()));