Index: llvm/trunk/test/tools/sancov/Inputs/blacklist.txt =================================================================== --- llvm/trunk/test/tools/sancov/Inputs/blacklist.txt +++ llvm/trunk/test/tools/sancov/Inputs/blacklist.txt @@ -0,0 +1 @@ +fun:bar* Index: llvm/trunk/test/tools/sancov/Inputs/test.cpp =================================================================== --- llvm/trunk/test/tools/sancov/Inputs/test.cpp +++ llvm/trunk/test/tools/sancov/Inputs/test.cpp @@ -1,5 +1,5 @@ // compile & generate coverage data using: -// clang++ -g -o test-linux_x86_64 -fsanitize=address -fsanitize-coverage=edge *.cpp +// clang++ -g -o test-linux_x86_64 -fsanitize=address -fsanitize-coverage=bb test.cpp foo.cpp // ASAN_OPTIONS="coverage=1" ./test-linux_x86_64 && mv test-linux_x86_64.*.sancov test-linux_x86_64.sancov // ASAN_OPTIONS="coverage=1" ./test-linux_x86_64 1 && mv test-linux_x86_64.*.sancov test-linux_x86_64-1.sancov Index: llvm/trunk/test/tools/sancov/blacklist.test =================================================================== --- llvm/trunk/test/tools/sancov/blacklist.test +++ llvm/trunk/test/tools/sancov/blacklist.test @@ -0,0 +1,5 @@ +REQUIRES: x86_64-linux +RUN: sancov -obj %p/Inputs/test-linux_x86_64 -covered-functions -blacklist %p/Inputs/blacklist.txt %p/Inputs/test-linux_x86_64.sancov | FileCheck %s + +CHECK-NOT: Inputs{{[/\\]}}test.cpp:12 bar(std::string) +CHECK: Inputs{{[/\\]}}test.cpp:14 main Index: llvm/trunk/test/tools/sancov/not_covered_functions.test =================================================================== --- llvm/trunk/test/tools/sancov/not_covered_functions.test +++ llvm/trunk/test/tools/sancov/not_covered_functions.test @@ -3,5 +3,6 @@ RUN: sancov -obj %p/Inputs/test-linux_x86_64 -not-covered-functions %p/Inputs/test-linux_x86_64-1.sancov | FileCheck --check-prefix=CHECK1 --allow-empty %s CHECK: Inputs{{[/\\]}}foo.cpp:5 foo() -CHECK1-NOT: {{.}}* +CHECK-NOT: {{.*__sanitizer.*}} +CHECK1-NOT: {{.+}} Index: llvm/trunk/test/tools/sancov/print.test =================================================================== --- llvm/trunk/test/tools/sancov/print.test +++ llvm/trunk/test/tools/sancov/print.test @@ -1,11 +1,11 @@ REQUIRES: x86_64-linux RUN: sancov -obj %p/Inputs/test-linux_x86_64 -print %p/Inputs/test-linux_x86_64.sancov | FileCheck %s -CHECK: 0x4db18b -CHECK: 0x4db2d2 -CHECK: 0x4db322 -CHECK: 0x4db376 -CHECK: 0x4db3bd -CHECK: 0x4db3f4 -CHECK: 0x4db427 -CHECK: 0x4db45a +CHECK: 0x4dbe2b +CHECK: 0x4dbf72 +CHECK: 0x4dbfec +CHECK: 0x4dc033 +CHECK: 0x4dc06a +CHECK: 0x4dc09d +CHECK: 0x4dc0d0 + Index: llvm/trunk/tools/sancov/sancov.cc =================================================================== --- llvm/trunk/tools/sancov/sancov.cc +++ llvm/trunk/tools/sancov/sancov.cc @@ -34,6 +34,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/SpecialCaseList.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" @@ -80,6 +81,16 @@ "strip_path_prefix", cl::init(""), cl::desc("Strip this prefix from file paths in reports.")); +static cl::opt + ClBlacklist("blacklist", cl::init(""), + cl::desc("Blacklist file (sanitizer blacklist format).")); + +static cl::opt ClUseDefaultBlacklist( + "use_default_blacklist", cl::init(true), cl::Hidden, + cl::desc("Controls if default blacklist should be used.")); + +static const char *const DefaultBlacklist = "fun:__sanitizer_*"; + // --------- FORMAT SPECIFICATION --------- struct FileHeader { @@ -169,8 +180,8 @@ for (auto Addr : Addrs) { auto InliningInfo = Symbolizer.symbolizeInlinedCode(ClBinaryName, Addr); FailIfError(InliningInfo); - for (uint32_t i = 0; i < InliningInfo->getNumberOfFrames(); ++i) { - auto FrameInfo = InliningInfo->getFrame(i); + for (uint32_t I = 0; I < InliningInfo->getNumberOfFrames(); ++I) { + auto FrameInfo = InliningInfo->getFrame(I); SmallString<256> FileName(FrameInfo.FileName); sys::path::remove_dots(FileName, /* remove_dot_dot */ true); FileLoc Loc = {FileName.str(), FrameInfo.Line}; @@ -186,7 +197,7 @@ std::set computeFunctionLocs(const std::set &Addrs) { std::map Fns = computeFunctionsMap(Addrs); - std::set result; + std::set Result; std::string LastFileName; std::set ProcessedFunctions; @@ -201,10 +212,10 @@ if (!ProcessedFunctions.insert(FunctionName).second) continue; - result.insert(FunctionLoc{P.first, P.second}); + Result.insert(FunctionLoc{P.first, P.second}); } - return result; + return Result; } // Locate __sanitizer_cov* function addresses that are used for coverage @@ -346,9 +357,41 @@ return Result; } +static std::unique_ptr createDefaultBlacklist() { + if (!ClUseDefaultBlacklist) + return std::unique_ptr(); + std::unique_ptr MB = + MemoryBuffer::getMemBuffer(DefaultBlacklist); + std::string Error; + auto Blacklist = SpecialCaseList::create(MB.get(), Error); + FailIfNotEmpty(Error); + return Blacklist; +} + +static std::unique_ptr createUserBlacklist() { + if (ClBlacklist.empty()) + return std::unique_ptr(); + + return SpecialCaseList::createOrDie({{ClBlacklist}}); +} + static void printFunctionLocs(const std::set &FnLocs, raw_ostream &OS) { + std::unique_ptr DefaultBlacklist = createDefaultBlacklist(); + std::unique_ptr UserBlacklist = createUserBlacklist(); + for (const FunctionLoc &FnLoc : FnLocs) { + if (DefaultBlacklist && + DefaultBlacklist->inSection("fun", FnLoc.FunctionName)) + continue; + if (DefaultBlacklist && + DefaultBlacklist->inSection("src", FnLoc.Loc.FileName)) + continue; + if (UserBlacklist && UserBlacklist->inSection("fun", FnLoc.FunctionName)) + continue; + if (UserBlacklist && UserBlacklist->inSection("src", FnLoc.Loc.FileName)) + continue; + OS << stripPathPrefix(FnLoc.Loc.FileName) << ":" << FnLoc.Loc.Line << " " << FnLoc.FunctionName << "\n"; }