forked from OSchip/llvm-project
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
This commit is contained in:
parent
b9b8027cee
commit
a511cdd247
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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?
|
||||
|
||||
// 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 {
|
||||
D.Diag(clang::diag::err_drv_no_such_file) << BLPath;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If no -fsanitize-blacklist option is specified, try to look up for
|
||||
// blacklist in the resource directory.
|
||||
// Setup blacklist files.
|
||||
// Add default blacklist from resource directory.
|
||||
{
|
||||
std::string BLPath;
|
||||
if (getDefaultBlacklist(D, BLPath) && llvm::sys::fs::exists(BLPath))
|
||||
BlacklistFile = BLPath;
|
||||
BlacklistFiles.push_back(BLPath);
|
||||
}
|
||||
// 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))
|
||||
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();
|
||||
}
|
||||
}
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue