Index: include/clang/Serialization/ASTReader.h =================================================================== --- include/clang/Serialization/ASTReader.h +++ include/clang/Serialization/ASTReader.h @@ -317,7 +317,31 @@ public ExternalSLocEntrySource { public: - typedef SmallVector RecordData; + class RecordData : public SmallVector { + public: + RecordData(ASTReader *AR) : AR(AR) {} + + reference operator[](size_type idx) { + if (AR && idx >= size()) { + AR->Error("Malformed record data, invalid access"); + return Poison; + } + return SmallVector::operator[](idx); + } + + const_reference operator[](size_type idx) const { + if (AR && idx >= size()) { + AR->Error("Malformed record data, invalid access"); + return Poison; + } + return SmallVector::operator[](idx); + } + + private: + ASTReader *AR; + uint64_t Poison; + }; + typedef SmallVectorImpl RecordDataImpl; /// \brief The result of reading the control block of an AST file, which Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -988,7 +988,7 @@ SavedStreamPosition SavedPosition(Cursor); Cursor.JumpToBit(Offset); - RecordData Record; + RecordData Record(this); StringRef Blob; unsigned Code = Cursor.ReadCode(); unsigned RecCode = Cursor.readRecord(Code, Record, &Blob); @@ -1024,7 +1024,7 @@ SavedStreamPosition SavedPosition(Cursor); Cursor.JumpToBit(Offset); - RecordData Record; + RecordData Record(this); StringRef Blob; unsigned Code = Cursor.ReadCode(); unsigned RecCode = Cursor.readRecord(Code, Record, &Blob); @@ -1130,7 +1130,7 @@ return true; } - RecordData Record; + RecordData Record(this); while (true) { llvm::BitstreamEntry E = SLocEntryCursor.advanceSkippingSubblocks(); @@ -1209,7 +1209,7 @@ auto ReadBuffer = [this]( BitstreamCursor &SLocEntryCursor, StringRef Name) -> std::unique_ptr { - RecordData Record; + RecordData Record(this); StringRef Blob; unsigned Code = SLocEntryCursor.ReadCode(); unsigned RecCode = SLocEntryCursor.readRecord(Code, Record, &Blob); @@ -1242,7 +1242,7 @@ return true; } - RecordData Record; + RecordData Record(this); StringRef Blob; switch (SLocEntryCursor.readRecord(Entry.ID, Record, &Blob)) { default: @@ -1410,7 +1410,7 @@ SavedStreamPosition SavedPosition(Stream); Stream.JumpToBit(Offset); - RecordData Record; + RecordData Record(this); SmallVector MacroArgs; MacroInfo *Macro = nullptr; @@ -1656,7 +1656,7 @@ BitstreamCursor Cursor = MacroCursor; Cursor.JumpToBit(I->MacroStartOffset); - RecordData Record; + RecordData Record(this); while (true) { llvm::BitstreamEntry E = Cursor.advanceSkippingSubblocks(); @@ -1798,7 +1798,7 @@ // We expect to see a sequence of PP_MODULE_MACRO records listing exported // macros, followed by a PP_MACRO_DIRECTIVE_HISTORY record with the complete // macro histroy. - RecordData Record; + RecordData Record(this); while (true) { llvm::BitstreamEntry Entry = Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd); @@ -1898,7 +1898,7 @@ Cursor.JumpToBit(F.InputFileOffsets[ID-1]); unsigned Code = Cursor.ReadCode(); - RecordData Record; + RecordData Record(this); StringRef Blob; unsigned Result = Cursor.readRecord(Code, Record, &Blob); @@ -2090,7 +2090,7 @@ return Failure; // Read all of the records in the options block. - RecordData Record; + RecordData Record(nullptr); ASTReadResult Result = Success; while (1) { llvm::BitstreamEntry Entry = Stream.advance(); @@ -2176,7 +2176,7 @@ } // Read all of the records and blocks in the control block. - RecordData Record; + RecordData Record(this); unsigned NumInputs = 0; unsigned NumUserInputs = 0; while (1) { @@ -2453,7 +2453,7 @@ } // Read all of the records and blocks for the AST file. - RecordData Record; + RecordData Record(this); while (1) { llvm::BitstreamEntry Entry = Stream.advance(); @@ -3888,7 +3888,7 @@ ASTReader::ASTReadResult ASTReader::ReadExtensionBlock(ModuleFile &F) { BitstreamCursor &Stream = F.Stream; - RecordData Record; + RecordData Record(this); while (true) { llvm::BitstreamEntry Entry = Stream.advance(); switch (Entry.Kind) { @@ -4087,7 +4087,7 @@ return 0; // Scan for SIGNATURE inside the control block. - ASTReader::RecordData Record; + ASTReader::RecordData Record(nullptr); while (1) { llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); if (Entry.Kind == llvm::BitstreamEntry::EndBlock || @@ -4133,7 +4133,7 @@ } // Scan for ORIGINAL_FILE inside the control block. - RecordData Record; + RecordData Record(nullptr); while (1) { llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); if (Entry.Kind == llvm::BitstreamEntry::EndBlock) @@ -4230,7 +4230,7 @@ bool NeedsImports = Listener.needsImportVisitation(); BitstreamCursor InputFilesCursor; - RecordData Record; + RecordData Record(nullptr); std::string ModuleDir; bool DoneWithControlBlock = false; while (!DoneWithControlBlock) { @@ -4323,7 +4323,7 @@ Cursor.JumpToBit(InputFileOffs[I]); unsigned Code = Cursor.ReadCode(); - RecordData Record; + RecordData Record(nullptr); StringRef Blob; bool shouldContinue = false; switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) { @@ -4430,7 +4430,7 @@ ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap(); bool First = true; Module *CurrentModule = nullptr; - RecordData Record; + RecordData Record(this); while (true) { llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks(); @@ -4895,7 +4895,7 @@ ReadSourceLocation(M, PPOffs.End)); PreprocessingRecord &PPRec = *PP.getPreprocessingRecord(); StringRef Blob; - RecordData Record; + RecordData Record(this); PreprocessorDetailRecordTypes RecType = (PreprocessorDetailRecordTypes)M.PreprocessorDetailCursor.readRecord( Entry.ID, Record, &Blob); @@ -5207,7 +5207,7 @@ unsigned Idx = 0; DeclsCursor.JumpToBit(Loc.Offset); - RecordData Record; + RecordData Record(this); unsigned Code = DeclsCursor.ReadCode(); switch ((TypeCode)DeclsCursor.readRecord(Code, Record)) { case TYPE_EXT_QUAL: { @@ -6318,7 +6318,7 @@ Cursor.JumpToBit(Loc.Offset); ReadingKindTracker ReadingKind(Read_Decl, *this); - RecordData Record; + RecordData Record(this); unsigned Code = Cursor.ReadCode(); unsigned RecCode = Cursor.readRecord(Code, Record); if (RecCode != DECL_CXX_CTOR_INITIALIZERS) { @@ -6348,7 +6348,7 @@ SavedStreamPosition SavedPosition(Cursor); Cursor.JumpToBit(Loc.Offset); ReadingKindTracker ReadingKind(Read_Decl, *this); - RecordData Record; + RecordData Record(this); unsigned Code = Cursor.ReadCode(); unsigned RecCode = Cursor.readRecord(Code, Record); if (RecCode != DECL_CXX_BASE_SPECIFIERS) { @@ -8234,7 +8234,7 @@ serialization::ModuleFile &F = *I->second; SavedStreamPosition SavedPosition(Cursor); - RecordData Record; + RecordData Record(this); while (true) { llvm::BitstreamEntry Entry = Cursor.advanceSkippingSubblocks(BitstreamCursor::AF_DontPopBlockAtEnd); Index: lib/Serialization/ASTReaderDecl.cpp =================================================================== --- lib/Serialization/ASTReaderDecl.cpp +++ lib/Serialization/ASTReaderDecl.cpp @@ -3129,7 +3129,7 @@ Deserializing ADecl(this); DeclsCursor.JumpToBit(Loc.Offset); - RecordData Record; + RecordData Record(this); unsigned Code = DeclsCursor.ReadCode(); unsigned Idx = 0; ASTDeclReader Reader(*this, *Loc.F, ID, RawLocation, Record,Idx); @@ -3408,7 +3408,7 @@ llvm::BitstreamCursor &Cursor = F->DeclsCursor; SavedStreamPosition SavedPosition(Cursor); Cursor.JumpToBit(Offset); - RecordData Record; + RecordData Record(this); unsigned Code = Cursor.ReadCode(); unsigned RecCode = Cursor.readRecord(Code, Record); (void)RecCode; @@ -3452,7 +3452,7 @@ SavedStreamPosition SavedPosition(Cursor); Cursor.JumpToBit(LocalOffset); - RecordData Record; + RecordData Record(this); unsigned Code = Cursor.ReadCode(); unsigned RecCode = Cursor.readRecord(Code, Record); (void)RecCode; Index: lib/Serialization/ASTReaderStmt.cpp =================================================================== --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -2575,7 +2575,7 @@ unsigned PrevNumStmts = StmtStack.size(); #endif - RecordData Record; + RecordData Record(this); unsigned Idx; ASTStmtReader Reader(*this, F, Cursor, Record, Idx); Stmt::EmptyShell Empty;