summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorBob Haarman <llvm@inglorion.net>2017-11-10 17:08:21 +0000
committerBob Haarman <llvm@inglorion.net>2017-11-10 17:08:21 +0000
commita17bd121850a7e1c57cd0bd9d7553b35a72f0c39 (patch)
tree062236c9a350bc0d3ff4cc68a4dbc73b1a817d47 /llvm
parent8760acb8e39313f6ba4288534560f6ebbc0e9c09 (diff)
downloadbcm5719-llvm-a17bd121850a7e1c57cd0bd9d7553b35a72f0c39.tar.gz
bcm5719-llvm-a17bd121850a7e1c57cd0bd9d7553b35a72f0c39.zip
LTO: don't fatal when value for cache key already exists
Summary: LTO/Caching.cpp uses file rename to atomically set the value for a cache key. On Windows, this fails when the destination file already exists. Previously, LLVM would report_fatal_error in such cases. However, because the old and the new value for the cache key are supposed to be equivalent, it actually doesn't matter which one we keep. This change makes it so that failing the rename when an openable file with the desired name already exists causes us to report success instead of fataling. Reviewers: pcc, hans Subscribers: mehdi_amini, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D39874 llvm-svn: 317899
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/LTO/Caching.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/llvm/lib/LTO/Caching.cpp b/llvm/lib/LTO/Caching.cpp
index 1708ab4c5c7..32fdd422187 100644
--- a/llvm/lib/LTO/Caching.cpp
+++ b/llvm/lib/LTO/Caching.cpp
@@ -14,9 +14,9 @@
#include "llvm/LTO/Caching.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Errc.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -72,10 +72,23 @@ Expected<NativeObjectCache> lto::localCache(StringRef CacheDirectoryPath,
MBOrErr.getError().message() + "\n");
// This is atomic on POSIX systems.
- if (auto EC = sys::fs::rename(TempFilename, EntryPath))
+ // On Windows, it can fail with permission denied if the destination
+ // file already exists. Since the existing file should be semantically
+ // equivalent to the one we are trying to write, we give AddBuffer
+ // a copy of the bytes we wrote in that case. We do this instead of
+ // just using the existing file, because the pruner might delete the
+ // file before we get a chance to use it.
+ auto EC = sys::fs::rename(TempFilename, EntryPath);
+ if (EC == errc::permission_denied) {
+ auto MBCopy = MemoryBuffer::getMemBufferCopy(
+ (*MBOrErr)->getBuffer(), EntryPath);
+ MBOrErr = std::move(MBCopy);
+ sys::fs::remove(TempFilename);
+ } else if (EC) {
report_fatal_error(Twine("Failed to rename temporary file ") +
TempFilename + " to " + EntryPath + ": " +
EC.message() + "\n");
+ }
AddBuffer(Task, std::move(*MBOrErr), EntryPath);
}
OpenPOWER on IntegriCloud