Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -72,6 +72,7 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" @@ -81,6 +82,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -826,13 +828,27 @@ llvm_unreachable("getAddressSpaceMapMangling() doesn't cover anything."); } +static std::vector +getRealPaths(llvm::vfs::FileSystem &VFS, llvm::ArrayRef Paths) { + std::vector Result; + llvm::SmallString<128> Buffer; + for (const auto &File : Paths) { + VFS.getRealPath(File, Buffer); + Result.push_back(Buffer.str()); + } + return Result; +} + ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins) : FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()), DependentTemplateSpecializationTypes(this_()), SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts), - SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), + SanitizerBL(new SanitizerBlacklist( + getRealPaths(SM.getFileManager().getVirtualFileSystem(), + LangOpts.SanitizerBlacklistFiles), + SM)), XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles, LangOpts.XRayNeverInstrumentFiles, LangOpts.XRayAttrListFiles, SM)), Index: clang/lib/Driver/SanitizerArgs.cpp =================================================================== --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -12,12 +12,13 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "clang/Driver/ToolChain.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/SpecialCaseList.h" #include "llvm/Support/TargetParser.h" +#include "llvm/Support/VirtualFileSystem.h" #include using namespace clang; @@ -119,7 +120,8 @@ static std::string toString(const clang::SanitizerSet &Sanitizers); static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, - std::vector &BlacklistFiles) { + std::vector &BlacklistFiles, + llvm::vfs::FileSystem &VFS) { struct Blacklist { const char *File; SanitizerMask Mask; @@ -141,7 +143,7 @@ clang::SmallString<64> Path(D.ResourceDir); llvm::sys::path::append(Path, "share", BL.File); - if (llvm::sys::fs::exists(Path)) + if (VFS.exists(Path)) BlacklistFiles.push_back(Path.str()); else if (BL.Mask == SanitizerKind::CFI) // If cfi_blacklist.txt cannot be found in the resource dir, driver @@ -557,14 +559,20 @@ // Setup blacklist files. // Add default blacklist from resource directory. - addDefaultBlacklists(D, Kinds, BlacklistFiles); + auto &VFS = TC.getVFS(); + addDefaultBlacklists(D, Kinds, BlacklistFiles, VFS); + + std::vector RealBlackListFiles = BlacklistFiles; // Parse -f(no-)sanitize-blacklist options. for (const auto *Arg : Args) { if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) { Arg->claim(); std::string BLPath = Arg->getValue(); - if (llvm::sys::fs::exists(BLPath)) { + if (VFS.exists(BLPath)) { BlacklistFiles.push_back(BLPath); + llvm::SmallString<128> RealBLPath; + VFS.getRealPath(BLPath, RealBLPath); + RealBlackListFiles.push_back(RealBLPath.str()); ExtraDeps.push_back(BLPath); } else { D.Diag(clang::diag::err_drv_no_such_file) << BLPath; @@ -579,7 +587,7 @@ { std::string BLError; std::unique_ptr SCL( - llvm::SpecialCaseList::create(BlacklistFiles, BLError)); + llvm::SpecialCaseList::create(RealBlackListFiles, BLError)); if (!SCL.get()) D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError; } Index: clang/test/Driver/Inputs/actual_file.txt =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/actual_file.txt @@ -0,0 +1 @@ + Index: clang/test/Driver/Inputs/vfsoverlay.yaml =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/vfsoverlay.yaml @@ -0,0 +1,12 @@ +{ + 'version': 0, + 'roots': [ + { 'name': 'DIR', 'type': 'directory', + 'contents': [ + { 'name': 'only_virtual_file.txt', 'type': 'file', + 'external-contents': 'DIR/actual_file.txt' + } + ] + } + ] +} Index: clang/test/Driver/vfsoverlay-sanitizers-blacklists.c =================================================================== --- /dev/null +++ clang/test/Driver/vfsoverlay-sanitizers-blacklists.c @@ -0,0 +1,8 @@ +// RUN: rm -rf %t.dir +// RUN: mkdir -p %t.dir +// RUN: cp %S/Inputs/actual_file.txt %T/actual_file.txt +// RUN: sed -e "s|DIR|%T|g" %S/Inputs/vfsoverlay.yaml > %T/vfsoverlay.yaml +// RUN: mkdir %t.dir/Inputs + +// RUN: %clang -### -ivfsoverlay %T/vfsoverlay.yaml -fsanitize=undefined -fsanitize-blacklist=%T/only_virtual_file.txt %s 2>&1 | FileCheck %s +// CHECK: only_virtual_file.txt Index: clang/tools/driver/driver.cpp =================================================================== --- clang/tools/driver/driver.cpp +++ clang/tools/driver/driver.cpp @@ -447,7 +447,40 @@ ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false); - Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags); + IntrusiveRefCntPtr VFS = + llvm::vfs::getRealFileSystem(); + bool ExpectingVFSOverlayFile = false; + for (const auto *A : argv) { + if (StringRef(A) == "-ivfsoverlay") { + ExpectingVFSOverlayFile = true; + continue; + } + + if (ExpectingVFSOverlayFile) { + llvm::ErrorOr> Buffer = + VFS->getBufferForFile(A); + if (!Buffer) { + Diags.Report(diag::err_drv_force_crash) + << A; // TODO err_missing_vfs_overlay_file + continue; + } + IntrusiveRefCntPtr VFSFromA = + llvm::vfs::getVFSFromYAML(std::move(Buffer.get()), + /*DiagHandler*/ nullptr, A, + /*DiagContext*/ nullptr, VFS); + if (!VFSFromA) { + Diags.Report(diag::err_drv_force_crash) + << A; // TODO err_invalid_vfs_overlay + continue; + } + VFS = VFSFromA; + } + + ExpectingVFSOverlayFile = false; + } + // TODO if(ExpectingVFSOverlayFile) report there's missing value + + Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags, VFS); SetInstallDir(argv, TheDriver, CanonicalPrefixes); TheDriver.setTargetAndMode(TargetAndMode);