The Next Win32 File System Problem

Fixing one bug uncovers the next one...

To reproduce:
llvm-ar rc ./libgcc.a libgcc/./_muldi3.o <and-lots-more-.o-files...>

The result:
  C:\msys\1.0\home\llvm_home\install\bin\llvm-ar.exe: Can't move './libgcc.a-000003' to './libgcc.a-000002': Cannot create a file when that file already exists.

So apparently, we're trying to move one file on top of another.

The error is generated in:

Path::renamePathOnDisk(const Path& newName) {
  if (!MoveFile(path.c_str(), newName.c_str()))
    ThrowError("Can't move '" + path +
               "' to '" + newName.path + "': ");
  return true;
}

I'm guessing that the last part of the error message ("Cannot create a
file when that file already exists") is the result of a GetLastError() ?

Here's a stack trace just before the exception is thrown:
Breakpoint 1, llvm::sys::Path::renamePathOnDisk(llvm::sys::Path const&) (
    this=0x22fc00, newName=@0x22fd20)
    at
C:/msys/1.0/home/llvm_home/llvm-build/../llvm/lib/System/Win32/Path.inc:685
685 if (!MoveFile(path.c_str(), newName.c_str()))
(gdb) n
686 ThrowError("Can't move '" + path +
(gdb) bt
#0 llvm::sys::Path::renamePathOnDisk(llvm::sys::Path const&)
(this=0x22fc00,
    newName=@0x22fd20)
    at
C:/msys/1.0/home/llvm_home/llvm-build/../llvm/lib/System/Win32/Path.inc:686
#1 0x004871c3 in llvm::Archive::writeToDisk(bool, bool, bool)
(this=0x3d5110,
    CreateSymbolTable=true, TruncateNames=false, Compress=false)
    at
C:/msys/1.0/home/llvm_home/llvm-build/../llvm/lib/Bytecode/Archive/ArchiveWriter.cpp:461
#2 0x00403d4d in doReplaceOrInsert() ()
    at
C:/msys/1.0/home/llvm_home/llvm-build/../llvm/tools/llvm-ar/llvm-ar.cpp:645
#3 0x004042b5 in main (argc=64, argv=0x3d4ca0)
    at
C:/msys/1.0/home/llvm_home/llvm-build/../llvm/tools/llvm-ar/llvm-ar.cpp:704
(gdb)

So how to fix this?:
1. These are both temp files right? Why are we trying to overwrite an
existing file during a MoveFile? Can we just choose a different temp file
name that doesn't exist yet?

2. Is it deliberate? Should we be deleting the target file and then
performing the MoveFile?

Yep, you found another bug. Unlike Unix, Windows does not allow a file to be implicitly replaced via renaming. I'll fix it.

Greg Pettyjohn wrote:

Fixed.

Jeff Cohen wrote: