diff options
-rw-r--r-- | clang/lib/Basic/SanitizerSpecialCaseList.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Basic/XRayLists.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Driver/SanitizerArgs.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Driver/XRayArgs.cpp | 6 | ||||
-rw-r--r-- | clang/unittests/Driver/CMakeLists.txt | 2 | ||||
-rw-r--r-- | clang/unittests/Driver/SanitizerArgsTest.cpp | 141 | ||||
-rw-r--r-- | llvm/include/llvm/Support/SpecialCaseList.h | 9 | ||||
-rw-r--r-- | llvm/lib/Support/SpecialCaseList.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 5 | ||||
-rw-r--r-- | llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/CodeCoverage.cpp | 5 | ||||
-rw-r--r-- | llvm/tools/sancov/sancov.cpp | 4 | ||||
-rw-r--r-- | llvm/unittests/Support/SpecialCaseListTest.cpp | 6 |
13 files changed, 188 insertions, 29 deletions
diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp index 7a820d4bef8..5bf8d39ffd9 100644 --- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp +++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp @@ -20,7 +20,7 @@ SanitizerSpecialCaseList::create(const std::vector<std::string> &Paths, std::string &Error) { std::unique_ptr<clang::SanitizerSpecialCaseList> SSCL( new SanitizerSpecialCaseList()); - if (SSCL->createInternal(Paths, Error, VFS)) { + if (SSCL->createInternal(Paths, VFS, Error)) { SSCL->createSanitizerSections(); return SSCL; } diff --git a/clang/lib/Basic/XRayLists.cpp b/clang/lib/Basic/XRayLists.cpp index eb549436710..222a28f79cc 100644 --- a/clang/lib/Basic/XRayLists.cpp +++ b/clang/lib/Basic/XRayLists.cpp @@ -17,10 +17,13 @@ XRayFunctionFilter::XRayFunctionFilter( ArrayRef<std::string> AlwaysInstrumentPaths, ArrayRef<std::string> NeverInstrumentPaths, ArrayRef<std::string> AttrListPaths, SourceManager &SM) - : AlwaysInstrument( - llvm::SpecialCaseList::createOrDie(AlwaysInstrumentPaths)), - NeverInstrument(llvm::SpecialCaseList::createOrDie(NeverInstrumentPaths)), - AttrList(llvm::SpecialCaseList::createOrDie(AttrListPaths)), SM(SM) {} + : AlwaysInstrument(llvm::SpecialCaseList::createOrDie( + AlwaysInstrumentPaths, SM.getFileManager().getVirtualFileSystem())), + NeverInstrument(llvm::SpecialCaseList::createOrDie( + NeverInstrumentPaths, SM.getFileManager().getVirtualFileSystem())), + AttrList(llvm::SpecialCaseList::createOrDie( + AttrListPaths, SM.getFileManager().getVirtualFileSystem())), + SM(SM) {} XRayFunctionFilter::ImbueAttribute XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const { diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 8937197c253..ac9a294ee3f 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -141,7 +141,7 @@ static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, clang::SmallString<64> Path(D.ResourceDir); llvm::sys::path::append(Path, "share", BL.File); - if (llvm::sys::fs::exists(Path)) + if (D.getVFS().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 @@ -563,7 +563,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) { Arg->claim(); std::string BLPath = Arg->getValue(); - if (llvm::sys::fs::exists(BLPath)) { + if (D.getVFS().exists(BLPath)) { UserBlacklistFiles.push_back(BLPath); } else { D.Diag(clang::diag::err_drv_no_such_file) << BLPath; @@ -578,14 +578,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, { std::string BLError; std::unique_ptr<llvm::SpecialCaseList> SCL( - llvm::SpecialCaseList::create(UserBlacklistFiles, BLError)); + llvm::SpecialCaseList::create(UserBlacklistFiles, D.getVFS(), BLError)); if (!SCL.get()) D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError; } { std::string BLError; - std::unique_ptr<llvm::SpecialCaseList> SCL( - llvm::SpecialCaseList::create(SystemBlacklistFiles, BLError)); + std::unique_ptr<llvm::SpecialCaseList> SCL(llvm::SpecialCaseList::create( + SystemBlacklistFiles, D.getVFS(), BLError)); if (!SCL.get()) D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError; } diff --git a/clang/lib/Driver/XRayArgs.cpp b/clang/lib/Driver/XRayArgs.cpp index 16e7c7ecf36..6011deaccc1 100644 --- a/clang/lib/Driver/XRayArgs.cpp +++ b/clang/lib/Driver/XRayArgs.cpp @@ -129,7 +129,7 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { // are treated as actual dependencies. for (const auto &Filename : Args.getAllArgValues(options::OPT_fxray_always_instrument)) { - if (llvm::sys::fs::exists(Filename)) { + if (D.getVFS().exists(Filename)) { AlwaysInstrumentFiles.push_back(Filename); ExtraDeps.push_back(Filename); } else @@ -138,7 +138,7 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { for (const auto &Filename : Args.getAllArgValues(options::OPT_fxray_never_instrument)) { - if (llvm::sys::fs::exists(Filename)) { + if (D.getVFS().exists(Filename)) { NeverInstrumentFiles.push_back(Filename); ExtraDeps.push_back(Filename); } else @@ -147,7 +147,7 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { for (const auto &Filename : Args.getAllArgValues(options::OPT_fxray_attr_list)) { - if (llvm::sys::fs::exists(Filename)) { + if (D.getVFS().exists(Filename)) { AttrListFiles.push_back(Filename); ExtraDeps.push_back(Filename); } else diff --git a/clang/unittests/Driver/CMakeLists.txt b/clang/unittests/Driver/CMakeLists.txt index 55b8a74830f..d0ab87bd9ea 100644 --- a/clang/unittests/Driver/CMakeLists.txt +++ b/clang/unittests/Driver/CMakeLists.txt @@ -9,10 +9,12 @@ add_clang_unittest(ClangDriverTests ToolChainTest.cpp ModuleCacheTest.cpp MultilibTest.cpp + SanitizerArgsTest.cpp ) clang_target_link_libraries(ClangDriverTests PRIVATE clangDriver clangBasic + clangFrontend # For TextDiagnosticPrinter. ) diff --git a/clang/unittests/Driver/SanitizerArgsTest.cpp b/clang/unittests/Driver/SanitizerArgsTest.cpp new file mode 100644 index 00000000000..164bc68051f --- /dev/null +++ b/clang/unittests/Driver/SanitizerArgsTest.cpp @@ -0,0 +1,141 @@ +//===- unittests/Driver/SanitizerArgsTest.cpp -----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Job.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" +#include "llvm/Support/raw_ostream.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include <cstdlib> +#include <memory> +#include <string> +using namespace clang; +using namespace clang::driver; + +using ::testing::Contains; +using ::testing::StrEq; + +namespace { + +static constexpr const char *ClangBinary = "clang"; +static constexpr const char *InputFile = "/sources/foo.c"; + +std::string concatPaths(llvm::ArrayRef<StringRef> Components) { + llvm::SmallString<128> P; + for (StringRef C : Components) + llvm::sys::path::append(P, C); + return P.str().str(); +} + +class SanitizerArgsTest : public ::testing::Test { +protected: + const Command &emulateSingleCompilation(std::vector<std::string> ExtraArgs, + std::vector<std::string> ExtraFiles) { + assert(!Driver && "Running twice is not allowed"); + + llvm::IntrusiveRefCntPtr<DiagnosticOptions> Opts = new DiagnosticOptions; + DiagnosticsEngine Diags( + new DiagnosticIDs, Opts, + new TextDiagnosticPrinter(llvm::errs(), Opts.get())); + Driver.emplace(ClangBinary, "x86_64-unknown-linux-gnu", Diags, + prepareFS(ExtraFiles)); + + std::vector<const char *> Args = {ClangBinary}; + for (const auto &A : ExtraArgs) + Args.push_back(A.c_str()); + Args.push_back("-c"); + Args.push_back(InputFile); + + Compilation.reset(Driver->BuildCompilation(Args)); + + if (Diags.hasErrorOccurred()) + ADD_FAILURE() << "Error occurred while parsing compilation arguments. " + "See stderr for details."; + + const auto &Commands = Compilation->getJobs().getJobs(); + assert(Commands.size() == 1); + return *Commands.front(); + } + +private: + llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> + prepareFS(llvm::ArrayRef<std::string> ExtraFiles) { + llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS = + new llvm::vfs::InMemoryFileSystem; + FS->addFile(ClangBinary, time_t(), llvm::MemoryBuffer::getMemBuffer("")); + FS->addFile(InputFile, time_t(), llvm::MemoryBuffer::getMemBuffer("")); + for (llvm::StringRef F : ExtraFiles) + FS->addFile(F, time_t(), llvm::MemoryBuffer::getMemBuffer("")); + return FS; + } + + llvm::Optional<Driver> Driver; + std::unique_ptr<driver::Compilation> Compilation; +}; + +TEST_F(SanitizerArgsTest, Blacklists) { + const std::string ResourceDir = "/opt/llvm/lib/resources"; + const std::string UserBlacklist = "/source/my_blacklist.txt"; + const std::string ASanBlacklist = + concatPaths({ResourceDir, "share", "asan_blacklist.txt"}); + + auto &Command = emulateSingleCompilation( + /*ExtraArgs=*/{"-fsanitize=address", "-resource-dir", ResourceDir, + std::string("-fsanitize-blacklist=") + UserBlacklist}, + /*ExtraFiles=*/{ASanBlacklist, UserBlacklist}); + + // System blacklists are added based on resource-dir. + EXPECT_THAT(Command.getArguments(), + Contains(StrEq(std::string("-fsanitize-system-blacklist=") + + ASanBlacklist))); + // User blacklists should also be added. + EXPECT_THAT( + Command.getArguments(), + Contains(StrEq(std::string("-fsanitize-blacklist=") + UserBlacklist))); +} + +TEST_F(SanitizerArgsTest, XRayLists) { + const std::string XRayWhitelist = "/source/xray_whitelist.txt"; + const std::string XRayBlacklist = "/source/xray_blacklist.txt"; + const std::string XRayAttrList = "/source/xray_attr_list.txt"; + + auto &Command = emulateSingleCompilation( + /*ExtraArgs=*/ + { + "-fxray-instrument", + "-fxray-always-instrument=" + XRayWhitelist, + "-fxray-never-instrument=" + XRayBlacklist, + "-fxray-attr-list=" + XRayAttrList, + }, + /*ExtraFiles=*/{XRayWhitelist, XRayBlacklist, XRayAttrList}); + + // Blacklists exist in the filesystem, so they should be added to the + // compilation command, produced by the driver. + EXPECT_THAT(Command.getArguments(), + Contains(StrEq("-fxray-always-instrument=" + XRayWhitelist))); + EXPECT_THAT(Command.getArguments(), + Contains(StrEq("-fxray-never-instrument=" + XRayBlacklist))); + EXPECT_THAT(Command.getArguments(), + Contains(StrEq("-fxray-attr-list=" + XRayAttrList))); +} + +} // namespace diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index 74a7a45312a..5b5b7f6124d 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -69,7 +69,8 @@ public: /// Parses the special case list entries from files. On failure, returns /// 0 and writes an error message to string. static std::unique_ptr<SpecialCaseList> - create(const std::vector<std::string> &Paths, std::string &Error); + create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS, + std::string &Error); /// Parses the special case list from a memory buffer. On failure, returns /// 0 and writes an error message to string. static std::unique_ptr<SpecialCaseList> create(const MemoryBuffer *MB, @@ -77,7 +78,7 @@ public: /// Parses the special case list entries from files. On failure, reports a /// fatal error. static std::unique_ptr<SpecialCaseList> - createOrDie(const std::vector<std::string> &Paths); + createOrDie(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS); ~SpecialCaseList(); @@ -103,8 +104,8 @@ public: protected: // Implementations of the create*() functions that can also be used by derived // classes. - bool createInternal(const std::vector<std::string> &Paths, std::string &Error, - vfs::FileSystem &VFS = *vfs::getRealFileSystem()); + bool createInternal(const std::vector<std::string> &Paths, + vfs::FileSystem &VFS, std::string &Error); bool createInternal(const MemoryBuffer *MB, std::string &Error); SpecialCaseList() = default; diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index 5812f075aa4..d1ff44cefb0 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Regex.h" +#include "llvm/Support/VirtualFileSystem.h" #include <string> #include <system_error> #include <utility> @@ -71,9 +72,9 @@ unsigned SpecialCaseList::Matcher::match(StringRef Query) const { std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const std::vector<std::string> &Paths, - std::string &Error) { + llvm::vfs::FileSystem &FS, std::string &Error) { std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList()); - if (SCL->createInternal(Paths, Error)) + if (SCL->createInternal(Paths, FS, Error)) return SCL; return nullptr; } @@ -87,15 +88,16 @@ std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB, } std::unique_ptr<SpecialCaseList> -SpecialCaseList::createOrDie(const std::vector<std::string> &Paths) { +SpecialCaseList::createOrDie(const std::vector<std::string> &Paths, + llvm::vfs::FileSystem &FS) { std::string Error; - if (auto SCL = create(Paths, Error)) + if (auto SCL = create(Paths, FS, Error)) return SCL; report_fatal_error(Error); } bool SpecialCaseList::createInternal(const std::vector<std::string> &Paths, - std::string &Error, vfs::FileSystem &VFS) { + vfs::FileSystem &VFS, std::string &Error) { StringMap<size_t> Sections; for (const auto &Path : Paths) { ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 6f5ec3d0852..cf9a6a321c7 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -88,6 +88,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SpecialCaseList.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" @@ -480,7 +481,9 @@ DataFlowSanitizer::DataFlowSanitizer( std::vector<std::string> AllABIListFiles(std::move(ABIListFiles)); AllABIListFiles.insert(AllABIListFiles.end(), ClABIListFiles.begin(), ClABIListFiles.end()); - ABIList.set(SpecialCaseList::createOrDie(AllABIListFiles)); + // FIXME: should we propagate vfs::FileSystem to this constructor? + ABIList.set( + SpecialCaseList::createOrDie(AllABIListFiles, *vfs::getRealFileSystem())); } FunctionType *DataFlowSanitizer::getArgsFunctionType(FunctionType *T) { diff --git a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp index c54e5383248..79bf63af5f4 100644 --- a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp +++ b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/SpecialCaseList.h" +#include "llvm/Support/VirtualFileSystem.h" #include <cstdlib> @@ -261,7 +262,8 @@ int main(int argc, char **argv) { std::unique_ptr<SpecialCaseList> SpecialCaseList; if (BlacklistFilename != "-") { std::string Error; - SpecialCaseList = SpecialCaseList::create({BlacklistFilename}, Error); + SpecialCaseList = SpecialCaseList::create({BlacklistFilename}, + *vfs::getRealFileSystem(), Error); if (!SpecialCaseList) { errs() << "Failed to get blacklist: " << Error << "\n"; exit(EXIT_FAILURE); diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 7151cfb032f..5f1e23f20d7 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/ThreadPool.h" #include "llvm/Support/Threading.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/VirtualFileSystem.h" #include <functional> #include <map> @@ -704,8 +705,8 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { // Read in -name-whitelist files. if (!NameFilterFiles.empty()) { std::string SpecialCaseListErr; - NameWhitelist = - SpecialCaseList::create(NameFilterFiles, SpecialCaseListErr); + NameWhitelist = SpecialCaseList::create( + NameFilterFiles, *vfs::getRealFileSystem(), SpecialCaseListErr); if (!NameWhitelist) error(SpecialCaseListErr); } diff --git a/llvm/tools/sancov/sancov.cpp b/llvm/tools/sancov/sancov.cpp index 1e6d92f6be8..2b9c181246b 100644 --- a/llvm/tools/sancov/sancov.cpp +++ b/llvm/tools/sancov/sancov.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/SpecialCaseList.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" @@ -510,7 +511,8 @@ private: if (ClBlacklist.empty()) return std::unique_ptr<SpecialCaseList>(); - return SpecialCaseList::createOrDie({{ClBlacklist}}); + return SpecialCaseList::createOrDie({{ClBlacklist}}, + *vfs::getRealFileSystem()); } std::unique_ptr<SpecialCaseList> DefaultBlacklist; std::unique_ptr<SpecialCaseList> UserBlacklist; diff --git a/llvm/unittests/Support/SpecialCaseListTest.cpp b/llvm/unittests/Support/SpecialCaseListTest.cpp index 2245588d97c..de1f058b67f 100644 --- a/llvm/unittests/Support/SpecialCaseListTest.cpp +++ b/llvm/unittests/Support/SpecialCaseListTest.cpp @@ -9,6 +9,7 @@ #include "llvm/Support/SpecialCaseList.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/VirtualFileSystem.h" #include "gtest/gtest.h" using namespace llvm; @@ -161,7 +162,8 @@ TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) { EXPECT_EQ("malformed regex in line 2: 'fun(a': parentheses not balanced", Error); std::vector<std::string> Files(1, "unexisting"); - EXPECT_EQ(nullptr, SpecialCaseList::create(Files, Error)); + EXPECT_EQ(nullptr, + SpecialCaseList::create(Files, *vfs::getRealFileSystem(), Error)); EXPECT_EQ(0U, Error.find("can't open file 'unexisting':")); } @@ -177,7 +179,7 @@ TEST_F(SpecialCaseListTest, MultipleBlacklists) { "src:ban=init\n")); Files.push_back(makeSpecialCaseListFile("src:baz\n" "src:*fog*\n")); - auto SCL = SpecialCaseList::createOrDie(Files); + auto SCL = SpecialCaseList::createOrDie(Files, *vfs::getRealFileSystem()); EXPECT_TRUE(SCL->inSection("", "src", "bar")); EXPECT_TRUE(SCL->inSection("", "src", "baz")); EXPECT_FALSE(SCL->inSection("", "src", "ban")); |