Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -412,7 +412,7 @@ if (llvm::sys::path::is_absolute(UseLinker)) { // If we're passed what looks like an absolute path, don't attempt to // second-guess that. - if (llvm::sys::fs::exists(UseLinker)) + if (llvm::sys::fs::can_execute(UseLinker)) return UseLinker; } else if (UseLinker.empty() || UseLinker == "ld") { // If we're passed -fuse-ld= with no argument, or with the argument ld, @@ -427,7 +427,7 @@ LinkerName.append(UseLinker); std::string LinkerPath(GetProgramPath(LinkerName.c_str())); - if (llvm::sys::fs::exists(LinkerPath)) + if (llvm::sys::fs::can_execute(LinkerPath)) return LinkerPath; } Index: test/Driver/fuse-ld-windows.c =================================================================== --- /dev/null +++ test/Driver/fuse-ld-windows.c @@ -0,0 +1,25 @@ +// REQUIRES: system-windows + +// We used to require adding ".exe" suffix when cross-compiling on Windows. +// RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ +// RUN: -B %S/Inputs/fuse_ld_windows -fuse-ld=foo 2>&1 \ +// RUN: | FileCheck %s + +// Check that the old variant still works. +// RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ +// RUN: -B %S/Inputs/fuse_ld_windows -fuse-ld=foo.exe 2>&1 \ +// RUN: | FileCheck %s + +// With the full path, the extension can be omitted, too, +// because Windows allows that. +// RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ +// RUN: -fuse-ld=%S/Inputs/fuse_ld_windows/ld.foo 2>&1 \ +// RUN: | FileCheck %s + +// Check that the full path with the extension works too. +// RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ +// RUN: -fuse-ld=%S/Inputs/fuse_ld_windows/ld.foo.exe 2>&1 \ +// RUN: | FileCheck %s + +// CHECK-NOT: invalid linker name +// CHECK: /Inputs/fuse_ld_windows{{/|\\\\}}ld.foo