Index: include/llvm/Support/FileSystem.h =================================================================== --- include/llvm/Support/FileSystem.h +++ include/llvm/Support/FileSystem.h @@ -554,7 +554,7 @@ /// This is an atomic operation. Either the file is created and opened, or the /// file system is left untouched. /// -/// The intendend use is for files that are to be kept, possibly after +/// The intended use is for files that are to be kept, possibly after /// renaming them. For example, when running 'clang -c foo.o', the file can /// be first created as foo-abc123.o and then renamed. /// Index: lib/Object/ArchiveWriter.cpp =================================================================== --- lib/Object/ArchiveWriter.cpp +++ lib/Object/ArchiveWriter.cpp @@ -305,9 +305,13 @@ std::vector &NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin) { + SmallString<128> AbsolutePath(ArcName); + if (auto EC = sys::fs::make_absolute(AbsolutePath)) + return std::make_pair(ArcName, EC); + SmallString<128> TmpArchive; int TmpArchiveFD; - if (auto EC = sys::fs::createUniqueFile(ArcName + ".temp-archive-%%%%%%%.a", + if (auto EC = sys::fs::createUniqueFile(AbsolutePath + ".temp-archive-%%%%%%%.a", TmpArchiveFD, TmpArchive)) return std::make_pair(ArcName, EC); Index: lib/Support/FileOutputBuffer.cpp =================================================================== --- lib/Support/FileOutputBuffer.cpp +++ lib/Support/FileOutputBuffer.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/Path.h" #include #if !defined(_MSC_VER) && !defined(__MINGW32__) @@ -68,9 +69,15 @@ Mode |= sys::fs::all_exe; // Create new file in same directory but with random name. - SmallString<128> TempFilePath; + SmallString<128> TempFilePath, AbsolutePath(FilePath); int FD; - EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD, + + AbsolutePath += ".tmp%%%%%%%"; + + EC = sys::fs::make_absolute(AbsolutePath); + if (EC) + return EC; + EC = sys::fs::createUniqueFile(Twine(AbsolutePath), FD, TempFilePath, Mode); if (EC) return EC; Index: lib/Support/Path.cpp =================================================================== --- lib/Support/Path.cpp +++ lib/Support/Path.cpp @@ -687,13 +687,13 @@ std::error_code createUniqueFile(const Twine &Model, int &ResultFd, SmallVectorImpl &ResultPath, unsigned Mode) { - return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File); + return createUniqueEntity(Model, ResultFd, ResultPath, true, Mode, FS_File); } std::error_code createUniqueFile(const Twine &Model, SmallVectorImpl &ResultPath) { int Dummy; - return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name); + return createUniqueEntity(Model, Dummy, ResultPath, true, 0, FS_Name); } static std::error_code Index: unittests/Support/Path.cpp =================================================================== --- unittests/Support/Path.cpp +++ unittests/Support/Path.cpp @@ -432,6 +432,7 @@ SmallString<64> TempPath2; ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD2, TempPath2)); ASSERT_TRUE(TempPath2.endswith(".temp")); + ASSERT_TRUE(!TempPath2.endswith("..temp")); ASSERT_NE(TempPath.str(), TempPath2.str()); fs::file_status A, B; @@ -498,6 +499,22 @@ ASSERT_NO_ERROR(fs::createTemporaryFile(Path216, "", TempPath)); ASSERT_NO_ERROR(fs::remove(Twine(TempPath))); #endif + + SmallString<64> AbsolutePath; + sys::path::system_temp_directory(true, AbsolutePath); + SmallString<64> UniquePath; + + // Pass an absolute model to createUniqueFile. The resulting + // path should still be absolute. + path::append(AbsolutePath, "unique%%%%%%.txt"); + ASSERT_NO_ERROR(fs::createUniqueFile(Twine(AbsolutePath), UniquePath)); + EXPECT_TRUE(path::is_absolute(UniquePath)); + + // Pass a relative model to createUniqueFile. The resulting + // path should be absolute. + Twine relativePath = Twine("unique%%%%%%.txt"); + ASSERT_NO_ERROR(fs::createUniqueFile(relativePath, UniquePath)); + EXPECT_TRUE(path::is_absolute(UniquePath)); } TEST_F(FileSystemTest, CreateDir) {