diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index cbbd485a9b7..53bf63e775d 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -341,19 +341,26 @@ std::string ToolChain::GetProgramPath(const char *Name) const { std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { - StringRef Suffix = A->getValue(); - - // If we're passed -fuse-ld= with no argument, or with the argument ld, - // then use whatever the default system linker is. - if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - - llvm::SmallString<8> LinkerName("ld."); - LinkerName.append(Suffix); - - std::string LinkerPath(GetProgramPath(LinkerName.c_str())); - if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; + StringRef UseLinker = A->getValue(); + + if (llvm::sys::path::is_absolute(UseLinker)) { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) + return UseLinker; + } else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") + return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) + return LinkerPath; + } getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; diff --git a/test/Driver/fuse-ld.c b/test/Driver/fuse-ld.c index bd25b8deb32..ca89eb99716 100644 --- a/test/Driver/fuse-ld.c +++ b/test/Driver/fuse-ld.c @@ -1,3 +1,9 @@ +// RUN: %clang %s -### \ +// RUN: -fuse-ld=/usr/local/bin/or1k-linux-ld 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ABSOLUTE-LD +// CHECK-ABSOLUTE-LD: /usr/local/bin/or1k-linux-ld + + // RUN: %clang %s -### \ // RUN: -target x86_64-unknown-freebsd 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-FREEBSD-LD