[clang] ba6f906 - [Driver] Use VFS to check if sanitizer blacklists exist
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 21 02:02:11 PST 2019
Author: Ilya Biryukov
Date: 2019-11-21T11:00:30+01:00
New Revision: ba6f906854263375cff3257d22d241a8a259cf77
URL: https://github.com/llvm/llvm-project/commit/ba6f906854263375cff3257d22d241a8a259cf77
DIFF: https://github.com/llvm/llvm-project/commit/ba6f906854263375cff3257d22d241a8a259cf77.diff
LOG: [Driver] Use VFS to check if sanitizer blacklists exist
Summary:
This is a follow-up to 590f279c456bbde632eca8ef89a85c478f15a249, which
moved some of the callers to use VFS.
It turned out more code in Driver calls into real filesystem APIs and
also needs an update.
Reviewers: gribozavr2, kadircet
Reviewed By: kadircet
Subscribers: ormris, mgorny, hiraditya, llvm-commits, jkorous, cfe-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D70440
Added:
clang/unittests/Driver/SanitizerArgsTest.cpp
Modified:
clang/lib/Basic/SanitizerSpecialCaseList.cpp
clang/lib/Basic/XRayLists.cpp
clang/lib/Driver/SanitizerArgs.cpp
clang/lib/Driver/XRayArgs.cpp
clang/unittests/Driver/CMakeLists.txt
llvm/include/llvm/Support/SpecialCaseList.h
llvm/lib/Support/SpecialCaseList.cpp
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
Removed:
################################################################################
diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
index 7a820d4bef86..5bf8d39ffd95 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 eb549436710a..222a28f79cc5 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 8937197c253c..ac9a294ee3fa 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 16e7c7ecf36b..6011deaccc1f 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 55b8a74830f4..d0ab87bd9ea8 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 000000000000..164bc68051f6
--- /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 74a7a45312aa..5b5b7f6124d6 100644
--- a/llvm/include/llvm/Support/SpecialCaseList.h
+++ b/llvm/include/llvm/Support/SpecialCaseList.h
@@ -69,7 +69,8 @@ class SpecialCaseList {
/// 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 @@ class SpecialCaseList {
/// 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 @@ class SpecialCaseList {
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 5812f075aa47..d1ff44cefb08 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 6f5ec3d08527..cf9a6a321c7a 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) {
More information about the cfe-commits
mailing list