From 12f4f8be904b16855952b0ea0355107b508cfbc3 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 15 Apr 2016 01:12:32 +0000 Subject: [PATCH] clang-cl: Don't check for existence of linker inputs when /link is used There might be flags passed to the linker (e.g. /libpath), causing it to search in paths the Clang driver doesn't know about. PR27234 llvm-svn: 266402 --- clang/lib/Driver/Driver.cpp | 23 ++++++++++++++++------- clang/test/Driver/cl-link.c | 8 ++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 64903de..9894323 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1115,7 +1115,7 @@ void Driver::BuildUniversalActions(Compilation &C, const ToolChain &TC, /// \brief Check that the file referenced by Value exists. If it doesn't, /// issue a diagnostic and return false. static bool DiagnoseInputExistence(const Driver &D, const DerivedArgList &Args, - StringRef Value) { + StringRef Value, types::ID Ty) { if (!D.getCheckInputsExist()) return true; @@ -1135,9 +1135,18 @@ static bool DiagnoseInputExistence(const Driver &D, const DerivedArgList &Args, if (llvm::sys::fs::exists(Twine(Path))) return true; - if (D.IsCLMode() && !llvm::sys::path::is_absolute(Twine(Path)) && - llvm::sys::Process::FindInEnvPath("LIB", Value)) - return true; + if (D.IsCLMode()) { + if (!llvm::sys::path::is_absolute(Twine(Path)) && + llvm::sys::Process::FindInEnvPath("LIB", Value)) + return true; + + if (Args.hasArg(options::OPT__SLASH_link) && Ty == types::TY_Object) { + // Arguments to the /link flag might cause the linker to search for object + // and library files in paths we don't know about. Don't error in such + // cases. + return true; + } + } D.Diag(clang::diag::err_drv_no_such_file) << Path; return false; @@ -1253,19 +1262,19 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, } } - if (DiagnoseInputExistence(*this, Args, Value)) + if (DiagnoseInputExistence(*this, Args, Value, Ty)) Inputs.push_back(std::make_pair(Ty, A)); } else if (A->getOption().matches(options::OPT__SLASH_Tc)) { StringRef Value = A->getValue(); - if (DiagnoseInputExistence(*this, Args, Value)) { + if (DiagnoseInputExistence(*this, Args, Value, types::TY_C)) { Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); Inputs.push_back(std::make_pair(types::TY_C, InputArg)); } A->claim(); } else if (A->getOption().matches(options::OPT__SLASH_Tp)) { StringRef Value = A->getValue(); - if (DiagnoseInputExistence(*this, Args, Value)) { + if (DiagnoseInputExistence(*this, Args, Value, types::TY_CXX)) { Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); Inputs.push_back(std::make_pair(types::TY_CXX, InputArg)); } diff --git a/clang/test/Driver/cl-link.c b/clang/test/Driver/cl-link.c index b3c0b64..026c433 100644 --- a/clang/test/Driver/cl-link.c +++ b/clang/test/Driver/cl-link.c @@ -43,3 +43,11 @@ // RUN: %clang_cl /Zi /Tc%s -### 2>&1 | FileCheck --check-prefix=DEBUG %s // DEBUG: link.exe // DEBUG: "-debug" + +// PR27234 +// RUN: %clang_cl /Tc%s nonexistent.obj -### /link /libpath:somepath 2>&1 | FileCheck --check-prefix=NONEXISTENT %s +// RUN: %clang_cl /Tc%s nonexistent.lib -### /link /libpath:somepath 2>&1 | FileCheck --check-prefix=NONEXISTENT %s +// NONEXISTENT-NOT: no such file +// NONEXISTENT: link.exe +// NONEXISTENT: "/libpath:somepath" +// NONEXISTENT: nonexistent -- 2.7.4