Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 5fa94c9

Browse files
committed
Fix ownership of the MemoryBuffer in a FrontendInputFile.
This fixes a possible crash on certain kinds of corrupted AST file, but checking in an AST file corrupted in just the right way will be a maintenance nightmare because the format changes frequently. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@312851 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 3d9068b commit 5fa94c9

File tree

5 files changed

+39
-25
lines changed

5 files changed

+39
-25
lines changed

include/clang/Basic/SourceManager.h

+17-8
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,6 @@ namespace SrcMgr {
212212
/// this content cache. This is used for performance analysis.
213213
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
214214

215-
void setBuffer(std::unique_ptr<llvm::MemoryBuffer> B) {
216-
assert(!Buffer.getPointer() && "MemoryBuffer already set.");
217-
Buffer.setPointer(B.release());
218-
Buffer.setInt(0);
219-
}
220-
221215
/// \brief Get the underlying buffer, returning NULL if the buffer is not
222216
/// yet available.
223217
llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); }
@@ -816,7 +810,22 @@ class SourceManager : public RefCountedBase<SourceManager> {
816810
SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
817811
int LoadedID = 0, unsigned LoadedOffset = 0,
818812
SourceLocation IncludeLoc = SourceLocation()) {
819-
return createFileID(createMemBufferContentCache(std::move(Buffer)),
813+
return createFileID(
814+
createMemBufferContentCache(Buffer.release(), /*DoNotFree*/ false),
815+
IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
816+
}
817+
818+
enum UnownedTag { Unowned };
819+
820+
/// \brief Create a new FileID that represents the specified memory buffer.
821+
///
822+
/// This does no caching of the buffer and takes ownership of the
823+
/// MemoryBuffer, so only pass a MemoryBuffer to this once.
824+
FileID createFileID(UnownedTag, llvm::MemoryBuffer *Buffer,
825+
SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
826+
int LoadedID = 0, unsigned LoadedOffset = 0,
827+
SourceLocation IncludeLoc = SourceLocation()) {
828+
return createFileID(createMemBufferContentCache(Buffer, /*DoNotFree*/true),
820829
IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
821830
}
822831

@@ -1699,7 +1708,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
16991708

17001709
/// \brief Create a new ContentCache for the specified memory buffer.
17011710
const SrcMgr::ContentCache *
1702-
createMemBufferContentCache(std::unique_ptr<llvm::MemoryBuffer> Buf);
1711+
createMemBufferContentCache(llvm::MemoryBuffer *Buf, bool DoNotFree);
17031712

17041713
FileID getFileIDSlow(unsigned SLocOffset) const;
17051714
FileID getFileIDLocal(unsigned SLocOffset) const;

include/clang/Frontend/FrontendOptions.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,24 @@ class FrontendInputFile {
128128
/// \brief The file name, or "-" to read from standard input.
129129
std::string File;
130130

131-
llvm::MemoryBuffer *Buffer;
131+
/// The input, if it comes from a buffer rather than a file. This object
132+
/// does not own the buffer, and the caller is responsible for ensuring
133+
/// that it outlives any users.
134+
llvm::MemoryBuffer *Buffer = nullptr;
132135

133136
/// \brief The kind of input, e.g., C source, AST file, LLVM IR.
134137
InputKind Kind;
135138

136139
/// \brief Whether we're dealing with a 'system' input (vs. a 'user' input).
137-
bool IsSystem;
140+
bool IsSystem = false;
138141

139142
public:
140-
FrontendInputFile() : Buffer(nullptr), Kind(), IsSystem(false) { }
143+
FrontendInputFile() { }
141144
FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
142-
: File(File.str()), Buffer(nullptr), Kind(Kind), IsSystem(IsSystem) { }
143-
FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind,
145+
: File(File.str()), Kind(Kind), IsSystem(IsSystem) { }
146+
FrontendInputFile(llvm::MemoryBuffer *Buffer, InputKind Kind,
144147
bool IsSystem = false)
145-
: Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { }
148+
: Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) { }
146149

147150
InputKind getKind() const { return Kind; }
148151
bool isSystem() const { return IsSystem; }

lib/Basic/SourceManager.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -409,15 +409,16 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt,
409409
}
410410

411411

412-
/// createMemBufferContentCache - Create a new ContentCache for the specified
413-
/// memory buffer. This does no caching.
414-
const ContentCache *SourceManager::createMemBufferContentCache(
415-
std::unique_ptr<llvm::MemoryBuffer> Buffer) {
412+
/// Create a new ContentCache for the specified memory buffer.
413+
/// This does no caching.
414+
const ContentCache *
415+
SourceManager::createMemBufferContentCache(llvm::MemoryBuffer *Buffer,
416+
bool DoNotFree) {
416417
// Add a new ContentCache to the MemBufferInfos list and return it.
417418
ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>();
418419
new (Entry) ContentCache();
419420
MemBufferInfos.push_back(Entry);
420-
Entry->setBuffer(std::move(Buffer));
421+
Entry->replaceBuffer(Buffer, DoNotFree);
421422
return Entry;
422423
}
423424

lib/Frontend/CompilerInstance.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -838,8 +838,8 @@ bool CompilerInstance::InitializeSourceManager(
838838
: Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
839839

840840
if (Input.isBuffer()) {
841-
SourceMgr.setMainFileID(SourceMgr.createFileID(
842-
std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind));
841+
SourceMgr.setMainFileID(SourceMgr.createFileID(SourceManager::Unowned,
842+
Input.getBuffer(), Kind));
843843
assert(SourceMgr.getMainFileID().isValid() &&
844844
"Couldn't establish MainFileID!");
845845
return true;

lib/Frontend/FrontendAction.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -754,10 +754,11 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
754754
goto failure;
755755

756756
// Reinitialize the main file entry to refer to the new input.
757-
if (!CI.InitializeSourceManager(FrontendInputFile(
758-
Buffer.release(), Input.getKind().withFormat(InputKind::Source),
759-
CurrentModule->IsSystem)))
760-
goto failure;
757+
auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
758+
auto &SourceMgr = CI.getSourceManager();
759+
auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
760+
assert(BufferID.isValid() && "couldn't creaate module buffer ID");
761+
SourceMgr.setMainFileID(BufferID);
761762
}
762763
}
763764

0 commit comments

Comments
 (0)