[serialization] Fix potential fall-off-the-end issues.

The way llvm::BitstreamCursor works is that reading an end-of-block
code will pop the current block off the stack, along with all its
record abbreviation codes. This means we’d no longer know how to
read any records. Fix this by telling the cursor not to auto-pop blocks
any time we’re doing a tentative read.

Swift SVN r6135
This commit is contained in:
Jordan Rose
2013-07-10 23:25:52 +00:00
parent b4fe4f098c
commit 1564fa7f10

View File

@@ -18,6 +18,8 @@
using namespace swift;
using namespace swift::serialization;
static constexpr const auto AF_DontPopBlockAtEnd =
llvm::BitstreamCursor::AF_DontPopBlockAtEnd;
static ModuleStatus
validateControlBlock(llvm::BitstreamCursor &cursor,
@@ -68,7 +70,7 @@ Pattern *ModuleFile::maybeReadPattern() {
SmallVector<uint64_t, 8> scratch;
auto next = DeclTypeCursor.advance();
auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
if (next.Kind != llvm::BitstreamEntry::Record)
return nullptr;
@@ -170,7 +172,7 @@ ProtocolConformance *ModuleFile::maybeReadConformance() {
BCOffsetRAII lastRecordOffset(DeclTypeCursor);
SmallVector<uint64_t, 8> scratch;
auto next = DeclTypeCursor.advance();
auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
if (next.Kind != llvm::BitstreamEntry::Record)
return nullptr;
@@ -229,7 +231,7 @@ GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC) {
SmallVector<uint64_t, 8> scratch;
StringRef blobData;
auto next = DeclTypeCursor.advance();
auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
if (next.Kind != llvm::BitstreamEntry::Record)
return nullptr;
@@ -254,7 +256,7 @@ GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC) {
lastRecordOffset.reset();
bool shouldContinue = true;
auto entry = DeclTypeCursor.advance();
auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
if (entry.Kind != llvm::BitstreamEntry::Record)
break;
@@ -888,7 +890,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
theClass->setConformances(ctx.AllocateCopy(conformanceBuf));
auto members = readMembers();
assert(members.hasValue() && "could not read struct members");
assert(members.hasValue() && "could not read class members");
theClass->setMembers(members.getValue(), SourceRange());
break;
@@ -1115,7 +1117,7 @@ Type ModuleFile::getType(TypeID TID) {
// The tuple record itself is empty. Read all trailing elements.
SmallVector<TupleTypeElt, 8> elements;
while (true) {
auto entry = DeclTypeCursor.advance();
auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
if (entry.Kind != llvm::BitstreamEntry::Record)
break;
@@ -1328,7 +1330,7 @@ Type ModuleFile::getType(TypeID TID) {
SmallVector<Substitution, 8> substitutions;
while (true) {
auto entry = DeclTypeCursor.advance();
auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
if (entry.Kind != llvm::BitstreamEntry::Record)
break;
@@ -1622,7 +1624,7 @@ ModuleFile::ModuleFile(llvm::OwningPtr<llvm::MemoryBuffer> &&input)
break;
}
topLevelEntry = cursor.advance(llvm::BitstreamCursor::AF_DontPopBlockAtEnd);
topLevelEntry = cursor.advance(AF_DontPopBlockAtEnd);
}
if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock)