From 21a8bed504a95df019771ab1a3dc9ecccfd9cfaa Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sun, 6 Dec 2009 05:43:36 +0000 Subject: Add a pretty horrible hack to prevent clang from crashing with inconsistent PCH files. - The issue is that PCH uses a stat cache, which may reference files which have been deleted or moved. In such cases ContentCache::getBuffer was returning 0 but most clients are incapable of dealing with this (i.e., they don't). For the time being, resolve this issue by just making up some invalid file contents and. Eventually we should detect that we are in an inconsistent situation and error out with a nice message that the PCH is out of date. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90699 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Basic/SourceManager.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'lib/Basic/SourceManager.cpp') diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index a3e72e8b40..354bf7befb 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -56,9 +56,25 @@ void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) { const llvm::MemoryBuffer *ContentCache::getBuffer(std::string *ErrorStr) const { // Lazily create the Buffer for ContentCaches that wrap files. if (!Buffer && Entry) { - // FIXME: Should we support a way to not have to do this check over - // and over if we cannot open the file? Buffer = MemoryBuffer::getFile(Entry->getName(), ErrorStr,Entry->getSize()); + + // If we were unable to open the file, then we are in an inconsistent + // situation where the content cache referenced a file which no longer + // exists. Most likely, we were using a stat cache with an invalid entry but + // the file could also have been removed during processing. Since we can't + // really deal with this situation, just create an empty buffer. + // + // FIXME: This is definitely not ideal, but our immediate clients can't + // currently handle returning a null entry here. Ideally we should detect + // that we are in an inconsistent situation and error out as quickly as + // possible. + if (!Buffer) { + const llvm::StringRef FillStr("<<>>\n"); + Buffer = MemoryBuffer::getNewMemBuffer(Entry->getSize(), ""); + char *Ptr = const_cast(Buffer->getBufferStart()); + for (unsigned i = 0, e = Entry->getSize(); i != e; ++i) + Ptr[i] = FillStr[i % FillStr.size()]; + } } return Buffer; } -- cgit v1.2.3-18-g5258