Skip to content

Commit a511cdd

Browse files
committedFeb 4, 2015
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
1 parent b9b8027 commit a511cdd

File tree

10 files changed

+55
-41
lines changed

10 files changed

+55
-41
lines changed
 

‎clang/include/clang/Basic/LangOptions.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "clang/Basic/Sanitizers.h"
2222
#include "clang/Basic/Visibility.h"
2323
#include <string>
24+
#include <vector>
2425

2526
namespace clang {
2627

@@ -70,9 +71,9 @@ class LangOptions : public LangOptionsBase {
7071
/// \brief Set of enabled sanitizers.
7172
SanitizerSet Sanitize;
7273

73-
/// \brief Path to blacklist file specifying which objects
74+
/// \brief Paths to blacklist files specifying which objects
7475
/// (files, functions, variables) should not be instrumented.
75-
std::string SanitizerBlacklistFile;
76+
std::vector<std::string> SanitizerBlacklistFiles;
7677

7778
clang::ObjCRuntime ObjCRuntime;
7879

‎clang/include/clang/Basic/SanitizerBlacklist.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ class SanitizerBlacklist {
2828
SourceManager &SM;
2929

3030
public:
31-
SanitizerBlacklist(StringRef BlacklistPath, SourceManager &SM);
31+
SanitizerBlacklist(const std::vector<std::string> &BlacklistPaths,
32+
SourceManager &SM);
3233
bool isBlacklistedGlobal(StringRef GlobalName,
3334
StringRef Category = StringRef()) const;
3435
bool isBlacklistedType(StringRef MangledTypeName,

‎clang/include/clang/Driver/SanitizerArgs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "llvm/Option/Arg.h"
1414
#include "llvm/Option/ArgList.h"
1515
#include <string>
16+
#include <vector>
1617

1718
namespace clang {
1819
namespace driver {
@@ -24,7 +25,7 @@ class SanitizerArgs {
2425
SanitizerSet Sanitizers;
2526
SanitizerSet RecoverableSanitizers;
2627

27-
std::string BlacklistFile;
28+
std::vector<std::string> BlacklistFiles;
2829
int SanitizeCoverage;
2930
int MsanTrackOrigins;
3031
int AsanFieldPadding;

‎clang/lib/AST/ASTContext.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -737,9 +737,8 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
737737
FILEDecl(nullptr), jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr),
738738
ucontext_tDecl(nullptr), BlockDescriptorType(nullptr),
739739
BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr),
740-
FirstLocalImport(), LastLocalImport(),
741-
SourceMgr(SM), LangOpts(LOpts),
742-
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFile, SM)),
740+
FirstLocalImport(), LastLocalImport(), SourceMgr(SM), LangOpts(LOpts),
741+
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
743742
AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
744743
Idents(idents), Selectors(sels), BuiltinInfo(builtins),
745744
DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr),

‎clang/lib/Basic/LangOptions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void LangOptions::resetNonModularOptions() {
3030
// FIXME: This should not be reset; modules can be different with different
3131
// sanitizer options (this affects __has_feature(address_sanitizer) etc).
3232
Sanitize.clear();
33-
SanitizerBlacklistFile.clear();
33+
SanitizerBlacklistFiles.clear();
3434

3535
CurrentModule.clear();
3636
ImplementationOfModule.clear();

‎clang/lib/Basic/SanitizerBlacklist.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515

1616
using namespace clang;
1717

18-
SanitizerBlacklist::SanitizerBlacklist(StringRef BlacklistPath,
19-
SourceManager &SM)
20-
: SCL(llvm::SpecialCaseList::createOrDie(BlacklistPath)), SM(SM) {}
18+
SanitizerBlacklist::SanitizerBlacklist(
19+
const std::vector<std::string> &BlacklistPaths, SourceManager &SM)
20+
: SCL(llvm::SpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {}
2121

2222
bool SanitizerBlacklist::isBlacklistedGlobal(StringRef GlobalName,
2323
StringRef Category) const {

‎clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
232232
const PassManagerBuilderWrapper &BuilderWrapper =
233233
static_cast<const PassManagerBuilderWrapper&>(Builder);
234234
const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
235-
PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFile));
235+
PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles));
236236
}
237237

238238
static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,

‎clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ bool SanitizerArgs::needsUnwindTables() const {
151151
void SanitizerArgs::clear() {
152152
Sanitizers.clear();
153153
RecoverableSanitizers.clear();
154-
BlacklistFile = "";
154+
BlacklistFiles.clear();
155155
SanitizeCoverage = 0;
156156
MsanTrackOrigins = 0;
157157
AsanFieldPadding = 0;
@@ -285,30 +285,34 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
285285
// -f(-no)sanitize=leak should change whether leak detection is enabled by
286286
// default in ASan?
287287

288+
// Setup blacklist files.
289+
// Add default blacklist from resource directory.
290+
{
291+
std::string BLPath;
292+
if (getDefaultBlacklist(D, BLPath) && llvm::sys::fs::exists(BLPath))
293+
BlacklistFiles.push_back(BLPath);
294+
}
288295
// Parse -f(no-)sanitize-blacklist options.
289-
if (Arg *BLArg = Args.getLastArg(options::OPT_fsanitize_blacklist,
290-
options::OPT_fno_sanitize_blacklist)) {
291-
if (BLArg->getOption().matches(options::OPT_fsanitize_blacklist)) {
292-
std::string BLPath = BLArg->getValue();
293-
if (llvm::sys::fs::exists(BLPath)) {
294-
// Validate the blacklist format.
295-
std::string BLError;
296-
std::unique_ptr<llvm::SpecialCaseList> SCL(
297-
llvm::SpecialCaseList::create(BLPath, BLError));
298-
if (!SCL.get())
299-
D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
300-
else
301-
BlacklistFile = BLPath;
302-
} else {
296+
for (const auto *Arg : Args) {
297+
if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) {
298+
Arg->claim();
299+
std::string BLPath = Arg->getValue();
300+
if (llvm::sys::fs::exists(BLPath))
301+
BlacklistFiles.push_back(BLPath);
302+
else
303303
D.Diag(clang::diag::err_drv_no_such_file) << BLPath;
304-
}
304+
} else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
305+
Arg->claim();
306+
BlacklistFiles.clear();
305307
}
306-
} else {
307-
// If no -fsanitize-blacklist option is specified, try to look up for
308-
// blacklist in the resource directory.
309-
std::string BLPath;
310-
if (getDefaultBlacklist(D, BLPath) && llvm::sys::fs::exists(BLPath))
311-
BlacklistFile = BLPath;
308+
}
309+
// Validate blacklists format.
310+
{
311+
std::string BLError;
312+
std::unique_ptr<llvm::SpecialCaseList> SCL(
313+
llvm::SpecialCaseList::create(BlacklistFiles, BLError));
314+
if (!SCL.get())
315+
D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
312316
}
313317

314318
// Parse -f[no-]sanitize-memory-track-origins[=level] options.
@@ -405,9 +409,9 @@ void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
405409
if (UbsanTrapOnError)
406410
CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
407411

408-
if (!BlacklistFile.empty()) {
412+
for (const auto &BLPath : BlacklistFiles) {
409413
SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
410-
BlacklistOpt += BlacklistFile;
414+
BlacklistOpt += BLPath;
411415
CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
412416
}
413417

‎clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1669,7 +1669,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
16691669
// -fsanitize-address-field-padding=N has to be a LangOpt, parse it here.
16701670
Opts.SanitizeAddressFieldPadding =
16711671
getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
1672-
Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
1672+
Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist);
16731673
}
16741674

16751675
static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,

‎clang/test/Driver/fsanitize-blacklist.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
// REQUIRES: clang-driver, shell
55

66
// RUN: echo "fun:foo" > %t.good
7+
// RUN: echo "fun:bar" > %t.second
78
// RUN: echo "badline" > %t.bad
89

9-
// RUN: %clang -fsanitize=address -fsanitize-blacklist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BLACKLIST
10-
// CHECK-BLACKLIST: -fsanitize-blacklist
10+
// RUN: %clang -fsanitize=address -fsanitize-blacklist=%t.good -fsanitize-blacklist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BLACKLIST
11+
// CHECK-BLACKLIST: -fsanitize-blacklist={{.*}}.good
12+
// CHECK-BLACKLIST: -fsanitize-blacklist={{.*}}.second
1113

1214
// Ignore -fsanitize-blacklist flag if there is no -fsanitize flag.
1315
// RUN: %clang -fsanitize-blacklist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SANITIZE
@@ -22,5 +24,11 @@
2224
// CHECK-NO-SUCH-FILE: error: no such file or directory: 'unexisting.txt'
2325

2426
// Driver properly reports malformed blacklist files.
25-
// RUN: %clang -fsanitize=address -fsanitize-blacklist=%t.bad %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BAD-BLACKLIST
26-
// CHECK-BAD-BLACKLIST: error: malformed sanitizer blacklist
27+
// 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
28+
// CHECK-BAD-BLACKLIST: error: malformed sanitizer blacklist: 'error parsing file '{{.*}}.bad': malformed line 1: 'badline''
29+
30+
// -fno-sanitize-blacklist disables all blacklists specified earlier.
31+
// 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
32+
// CHECK-ONLY_FIRST-DISABLED-NOT: good
33+
// CHECK-ONLY-FIRST-DISABLED: -fsanitize-blacklist={{.*}}.second
34+
// CHECK-ONLY_FIRST-DISABLED-NOT: good

0 commit comments

Comments
 (0)
Please sign in to comment.