Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -5970,9 +5970,16 @@ Names.emplace_back(Tool); } -static bool ScanDirForExecutable(SmallString<128> &Dir, StringRef Name) { +static bool canExecute(llvm::vfs::FileSystem &VFS, StringRef Path) { + auto Status = VFS.status(Path); + return Status && + (Status->getPermissions() & llvm::sys::fs::perms::all_exe) != 0; +} + +static bool ScanDirForExecutable(llvm::vfs::FileSystem &VFS, + SmallString<128> &Dir, StringRef Name) { llvm::sys::path::append(Dir, Name); - if (llvm::sys::fs::can_execute(Twine(Dir))) + if (canExecute(VFS, Dir)) return true; llvm::sys::path::remove_filename(Dir); return false; @@ -5985,13 +5992,14 @@ // Respect a limited subset of the '-Bprefix' functionality in GCC by // attempting to use this prefix when looking for program paths. for (const auto &PrefixDir : PrefixDirs) { - if (llvm::sys::fs::is_directory(PrefixDir)) { + auto Status = getVFS().status(PrefixDir); + if (Status && Status->isDirectory()) { SmallString<128> P(PrefixDir); - if (ScanDirForExecutable(P, Name)) + if (ScanDirForExecutable(getVFS(), P, Name)) return std::string(P.str()); } else { SmallString<128> P((PrefixDir + Name).str()); - if (llvm::sys::fs::can_execute(Twine(P))) + if (canExecute(getVFS(), P)) return std::string(P.str()); } } @@ -6007,7 +6015,7 @@ // of gcc in the program path for (const auto &Path : List) { SmallString<128> P(Path); - if (ScanDirForExecutable(P, TargetSpecificExecutable)) + if (ScanDirForExecutable(getVFS(), P, TargetSpecificExecutable)) return std::string(P.str()); }