aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-06 01:26:49 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-06 01:26:49 +0000
commitda41af9e9423eeb435bbf64f94649726569ae45b (patch)
tree83c921701ee73320f6a6f0dfc313639105f22797 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parent597dcc7a8deb329037175f79bd0bd406a2aa880b (diff)
downloadllvm-da41af9e9423eeb435bbf64f94649726569ae45b.zip
llvm-da41af9e9423eeb435bbf64f94649726569ae45b.tar.gz
llvm-da41af9e9423eeb435bbf64f94649726569ae45b.tar.bz2
IR: Disallow complicated function-local metadata
Disallow complex types of function-local metadata. The only valid function-local metadata is an `MDNode` whose sole argument is a non-metadata function-local value. Part of PR21532. llvm-svn: 223564
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp36
1 files changed, 30 insertions, 6 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 25efa60..9f6d02f 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1072,7 +1072,6 @@ std::error_code BitcodeReader::ParseMetadata() {
break;
}
- bool IsFunctionLocal = false;
// Read a record.
Record.clear();
unsigned Code = Stream.readRecord(Entry.ID, Record);
@@ -1100,9 +1099,34 @@ std::error_code BitcodeReader::ParseMetadata() {
}
break;
}
- case bitc::METADATA_FN_NODE:
- IsFunctionLocal = true;
- // fall-through
+ case bitc::METADATA_FN_NODE: {
+ // This is a function-local node.
+ if (Record.size() % 2 == 1)
+ return Error(BitcodeError::InvalidRecord);
+
+ // If this isn't a single-operand node that directly references
+ // non-metadata, we're dropping it. This used to be legal, but there's
+ // no upgrade path.
+ auto dropRecord = [&] {
+ MDValueList.AssignValue(MDNode::get(Context, None), NextMDValueNo++);
+ };
+ if (Record.size() != 2) {
+ dropRecord();
+ break;
+ }
+
+ Type *Ty = getTypeByID(Record[0]);
+ if (Ty->isMetadataTy() || Ty->isVoidTy()) {
+ dropRecord();
+ break;
+ }
+
+ Value *Elts[] = {ValueList.getValueFwdRef(Record[1], Ty)};
+ Value *V = MDNode::getWhenValsUnresolved(Context, Elts,
+ /*IsFunctionLocal*/ true);
+ MDValueList.AssignValue(V, NextMDValueNo++);
+ break;
+ }
case bitc::METADATA_NODE: {
if (Record.size() % 2 == 1)
return Error(BitcodeError::InvalidRecord);
@@ -1120,8 +1144,8 @@ std::error_code BitcodeReader::ParseMetadata() {
else
Elts.push_back(nullptr);
}
- Value *V = MDNode::getWhenValsUnresolved(Context, Elts, IsFunctionLocal);
- IsFunctionLocal = false;
+ Value *V = MDNode::getWhenValsUnresolved(Context, Elts,
+ /*IsFunctionLocal*/ false);
MDValueList.AssignValue(V, NextMDValueNo++);
break;
}