summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-02 14:55:01 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-02 14:55:01 +0000
commit8742de9b20eb8b1960403842b38dcf0c80aa586b (patch)
tree950b446d4fc4bb27571de9246d02a63476c9dd06 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parenta2c8da9e0613fd1a05b7c1342de9b4f6e41473ed (diff)
downloadbcm5719-llvm-8742de9b20eb8b1960403842b38dcf0c80aa586b.tar.gz
bcm5719-llvm-8742de9b20eb8b1960403842b38dcf0c80aa586b.zip
BitcodeReader: Check for unresolved function metadata
A follow-up commit will start using function metadata blocks more heavily. This commit adds some error checking to confirm that metadata is fully resolved before (and after) materializing each function. This is valid even when reading very old bitcode from before the metadata/value split. The global metadata block always came before the function blocks. However, in case somehow this causes a regression (i.e., an old LLVM did produce such bitcode after all) I'm committing separately. llvm-svn: 265223
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 3598debd636..e784c88344d 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -123,6 +123,7 @@ public:
void shrinkTo(unsigned N) {
assert(N <= size() && "Invalid shrinkTo request!");
+ assert(!AnyFwdRefs && "Unexpected forward refs");
MetadataPtrs.resize(N);
}
@@ -130,6 +131,7 @@ public:
MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
void assignValue(Metadata *MD, unsigned Idx);
void tryToResolveCycles();
+ bool hasFwdRefs() const { return AnyFwdRefs; }
};
class BitcodeReader : public GVMaterializer {
@@ -1929,6 +1931,9 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
IsMetadataMaterialized = true;
unsigned NextMetadataNo = MetadataList.size();
+ if (!ModuleLevel && MetadataList.hasFwdRefs())
+ return error("Invalid metadata: fwd refs into function blocks");
+
if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
return error("Invalid record");
@@ -3968,6 +3973,10 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
return error("Invalid record");
+ // Unexpected unresolved metadata when parsing function.
+ if (MetadataList.hasFwdRefs())
+ return error("Invalid function metadata: incoming forward references");
+
InstructionList.clear();
unsigned ModuleValueListSize = ValueList.size();
unsigned ModuleMetadataListSize = MetadataList.size();
@@ -5227,8 +5236,9 @@ OutOfRecordLoop:
}
}
- // FIXME: Check for unresolved forward-declared metadata references
- // and clean up leaks.
+ // Unexpected unresolved metadata about to be dropped.
+ if (MetadataList.hasFwdRefs())
+ return error("Invalid function metadata: outgoing forward refs");
// Trim the value list down to the size it was before we parsed this function.
ValueList.shrinkTo(ModuleValueListSize);
OpenPOWER on IntegriCloud