aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2015-02-04 17:40:08 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2015-02-04 17:40:08 +0000
commita511cdd247777d947a2850d3e9c53d0bda19d6d5 (patch)
tree6d550133e7d4403b9c7d99397eaa3548497550e9
parentb9b8027ceec93ad9ed02d5b68130ccf5f06ae30b (diff)
downloadllvm-a511cdd247777d947a2850d3e9c53d0bda19d6d5.zip
llvm-a511cdd247777d947a2850d3e9c53d0bda19d6d5.tar.gz
llvm-a511cdd247777d947a2850d3e9c53d0bda19d6d5.tar.bz2
Allow to specify multiple -fsanitize-blacklist= arguments.
Summary: Allow user to provide multiple blacklists by passing several -fsanitize-blacklist= options. These options now don't override default blacklist from Clang resource directory, which is always applied (which fixes PR22431). -fno-sanitize-blacklist option now disables all blacklists that were specified earlier in the command line (including the default one). This change depends on http://reviews.llvm.org/D7367. Test Plan: regression test suite Reviewers: timurrrr Subscribers: cfe-commits, kcc, pcc Differential Revision: http://reviews.llvm.org/D7368 llvm-svn: 228156
-rw-r--r--clang/include/clang/Basic/LangOptions.h5
-rw-r--r--clang/include/clang/Basic/SanitizerBlacklist.h3
-rw-r--r--clang/include/clang/Driver/SanitizerArgs.h3
-rw-r--r--clang/lib/AST/ASTContext.cpp5
-rw-r--r--clang/lib/Basic/LangOptions.cpp2
-rw-r--r--clang/lib/Basic/SanitizerBlacklist.cpp6
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp2
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp52
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/test/Driver/fsanitize-blacklist.c16
10 files changed, 55 insertions, 41 deletions
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index a021be1..8edfa4b 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -21,6 +21,7 @@
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/Visibility.h"
#include <string>
+#include <vector>
namespace clang {
@@ -70,9 +71,9 @@ public:
/// \brief Set of enabled sanitizers.
SanitizerSet Sanitize;
- /// \brief Path to blacklist file specifying which objects
+ /// \brief Paths to blacklist files specifying which objects
/// (files, functions, variables) should not be instrumented.
- std::string SanitizerBlacklistFile;
+ std::vector<std::string> SanitizerBlacklistFiles;
clang::ObjCRuntime ObjCRuntime;
diff --git a/clang/include/clang/Basic/SanitizerBlacklist.h b/clang/include/clang/Basic/SanitizerBlacklist.h
index 2ce268a..e651e18 100644
--- a/clang/include/clang/Basic/SanitizerBlacklist.h
+++ b/clang/include/clang/Basic/SanitizerBlacklist.h
@@ -28,7 +28,8 @@ class SanitizerBlacklist {
SourceManager &SM;
public:
- SanitizerBlacklist(StringRef BlacklistPath, SourceManager &SM);
+ SanitizerBlacklist(const std::vector<std::string> &BlacklistPaths,
+ SourceManager &SM);
bool isBlacklistedGlobal(StringRef GlobalName,
StringRef Category = StringRef()) const;
bool isBlacklistedType(StringRef MangledTypeName,
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 3524da0..c51fae3 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -13,6 +13,7 @@
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include <string>
+#include <vector>
namespace clang {
namespace driver {
@@ -24,7 +25,7 @@ class SanitizerArgs {
SanitizerSet Sanitizers;
SanitizerSet RecoverableSanitizers;
- std::string BlacklistFile;
+ std::vector<std::string> BlacklistFiles;
int SanitizeCoverage;
int MsanTrackOrigins;
int AsanFieldPadding;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index d480277..68ae314 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -737,9 +737,8 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
FILEDecl(nullptr), jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr),
ucontext_tDecl(nullptr), BlockDescriptorType(nullptr),
BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr),
- FirstLocalImport(), LastLocalImport(),
- SourceMgr(SM), LangOpts(LOpts),
- SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFile, SM)),
+ FirstLocalImport(), LastLocalImport(), SourceMgr(SM), LangOpts(LOpts),
+ SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
Idents(idents), Selectors(sels), BuiltinInfo(builtins),
DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr),
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index dcbd228..2c87845 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -30,7 +30,7 @@ void LangOptions::resetNonModularOptions() {
// FIXME: This should not be reset; modules can be different with different
// sanitizer options (this affects __has_feature(address_sanitizer) etc).
Sanitize.clear();
- SanitizerBlacklistFile.clear();
+ SanitizerBlacklistFiles.clear();
CurrentModule.clear();
ImplementationOfModule.clear();
diff --git a/clang/lib/Basic/SanitizerBlacklist.cpp b/clang/lib/Basic/SanitizerBlacklist.cpp
index ea5b8d0..095fcd6 100644
--- a/clang/lib/Basic/SanitizerBlacklist.cpp
+++ b/clang/lib/Basic/SanitizerBlacklist.cpp
@@ -15,9 +15,9 @@
using namespace clang;
-SanitizerBlacklist::SanitizerBlacklist(StringRef BlacklistPath,
- SourceManager &SM)
- : SCL(llvm::SpecialCaseList::createOrDie(BlacklistPath)), SM(SM) {}
+SanitizerBlacklist::SanitizerBlacklist(
+ const std::vector<std::string> &BlacklistPaths, SourceManager &SM)
+ : SCL(llvm::SpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {}
bool SanitizerBlacklist::isBlacklistedGlobal(StringRef GlobalName,
StringRef Category) const {
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index c4cea02..de57165 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -232,7 +232,7 @@ static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
const PassManagerBuilderWrapper &BuilderWrapper =
static_cast<const PassManagerBuilderWrapper&>(Builder);
const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
- PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFile));
+ PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles));
}
static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 2740239..037fff2 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -151,7 +151,7 @@ bool SanitizerArgs::needsUnwindTables() const {
void SanitizerArgs::clear() {
Sanitizers.clear();
RecoverableSanitizers.clear();
- BlacklistFile = "";
+ BlacklistFiles.clear();
SanitizeCoverage = 0;
MsanTrackOrigins = 0;
AsanFieldPadding = 0;
@@ -285,30 +285,34 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// -f(-no)sanitize=leak should change whether leak detection is enabled by
// default in ASan?
+ // Setup blacklist files.
+ // Add default blacklist from resource directory.
+ {
+ std::string BLPath;
+ if (getDefaultBlacklist(D, BLPath) && llvm::sys::fs::exists(BLPath))
+ BlacklistFiles.push_back(BLPath);
+ }
// Parse -f(no-)sanitize-blacklist options.
- if (Arg *BLArg = Args.getLastArg(options::OPT_fsanitize_blacklist,
- options::OPT_fno_sanitize_blacklist)) {
- if (BLArg->getOption().matches(options::OPT_fsanitize_blacklist)) {
- std::string BLPath = BLArg->getValue();
- if (llvm::sys::fs::exists(BLPath)) {
- // Validate the blacklist format.
- std::string BLError;
- std::unique_ptr<llvm::SpecialCaseList> SCL(
- llvm::SpecialCaseList::create(BLPath, BLError));
- if (!SCL.get())
- D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
- else
- BlacklistFile = BLPath;
- } else {
+ 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))
+ BlacklistFiles.push_back(BLPath);
+ else
D.Diag(clang::diag::err_drv_no_such_file) << BLPath;
- }
+ } else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
+ Arg->claim();
+ BlacklistFiles.clear();
}
- } else {
- // If no -fsanitize-blacklist option is specified, try to look up for
- // blacklist in the resource directory.
- std::string BLPath;
- if (getDefaultBlacklist(D, BLPath) && llvm::sys::fs::exists(BLPath))
- BlacklistFile = BLPath;
+ }
+ // Validate blacklists format.
+ {
+ std::string BLError;
+ std::unique_ptr<llvm::SpecialCaseList> SCL(
+ llvm::SpecialCaseList::create(BlacklistFiles, BLError));
+ if (!SCL.get())
+ D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
}
// Parse -f[no-]sanitize-memory-track-origins[=level] options.
@@ -405,9 +409,9 @@ void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
if (UbsanTrapOnError)
CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
- if (!BlacklistFile.empty()) {
+ for (const auto &BLPath : BlacklistFiles) {
SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
- BlacklistOpt += BlacklistFile;
+ BlacklistOpt += BLPath;
CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 3b7fbb0..f8d71ac 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1669,7 +1669,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// -fsanitize-address-field-padding=N has to be a LangOpt, parse it here.
Opts.SanitizeAddressFieldPadding =
getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
- Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
+ Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist);
}
static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
diff --git a/clang/test/Driver/fsanitize-blacklist.c b/clang/test/Driver/fsanitize-blacklist.c
index 690bc87..b63ac34 100644
--- a/clang/test/Driver/fsanitize-blacklist.c
+++ b/clang/test/Driver/fsanitize-blacklist.c
@@ -4,10 +4,12 @@
// REQUIRES: clang-driver, shell
// RUN: echo "fun:foo" > %t.good
+// RUN: echo "fun:bar" > %t.second
// RUN: echo "badline" > %t.bad
-// RUN: %clang -fsanitize=address -fsanitize-blacklist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BLACKLIST
-// CHECK-BLACKLIST: -fsanitize-blacklist
+// RUN: %clang -fsanitize=address -fsanitize-blacklist=%t.good -fsanitize-blacklist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BLACKLIST
+// CHECK-BLACKLIST: -fsanitize-blacklist={{.*}}.good
+// CHECK-BLACKLIST: -fsanitize-blacklist={{.*}}.second
// Ignore -fsanitize-blacklist flag if there is no -fsanitize flag.
// RUN: %clang -fsanitize-blacklist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SANITIZE
@@ -22,5 +24,11 @@
// CHECK-NO-SUCH-FILE: error: no such file or directory: 'unexisting.txt'
// Driver properly reports malformed blacklist files.
-// RUN: %clang -fsanitize=address -fsanitize-blacklist=%t.bad %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BAD-BLACKLIST
-// CHECK-BAD-BLACKLIST: error: malformed sanitizer blacklist
+// RUN: %clang -fsanitize=address -fsanitize-blacklist=%t.second -fsanitize-blacklist=%t.bad -fsanitize-blacklist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BAD-BLACKLIST
+// CHECK-BAD-BLACKLIST: error: malformed sanitizer blacklist: 'error parsing file '{{.*}}.bad': malformed line 1: 'badline''
+
+// -fno-sanitize-blacklist disables all blacklists specified earlier.
+// RUN: %clang -fsanitize=address -fsanitize-blacklist=%t.good -fno-sanitize-blacklist -fsanitize-blacklist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-FIRST-DISABLED
+// CHECK-ONLY_FIRST-DISABLED-NOT: good
+// CHECK-ONLY-FIRST-DISABLED: -fsanitize-blacklist={{.*}}.second
+// CHECK-ONLY_FIRST-DISABLED-NOT: good