Index: include/clang/Frontend/DependencyOutputOptions.h =================================================================== --- include/clang/Frontend/DependencyOutputOptions.h +++ include/clang/Frontend/DependencyOutputOptions.h @@ -47,6 +47,9 @@ /// must contain at least one entry. std::vector Targets; + /// A list of filenames to be used as extra dependencies for every target. + std::vector ExtraDeps; + /// \brief The file to write GraphViz-formatted header dependencies to. std::string DOTOutputFile; Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -705,6 +705,10 @@ Args.getLastArgValue(OPT_module_dependency_dir); if (Args.hasArg(OPT_MV)) Opts.OutputFormat = DependencyOutputFormat::NMake; + // Add sanitizer blacklists as extra dependencies. + // They won't be discovered by the regular preprocessor, so + // we let make / ninja to know about this implicit dependency. + Opts.ExtraDeps = Args.getAllArgValues(OPT_fsanitize_blacklist); } bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Index: lib/Frontend/DependencyFile.cpp =================================================================== --- lib/Frontend/DependencyFile.cpp +++ lib/Frontend/DependencyFile.cpp @@ -162,6 +162,7 @@ const Preprocessor *PP; std::string OutputFile; std::vector Targets; + std::vector ExtraDeps; bool IncludeSystemHeaders; bool PhonyTarget; bool AddMissingHeaderDeps; @@ -177,6 +178,7 @@ public: DFGImpl(const Preprocessor *_PP, const DependencyOutputOptions &Opts) : PP(_PP), OutputFile(Opts.OutputFile), Targets(Opts.Targets), + ExtraDeps(Opts.ExtraDeps), IncludeSystemHeaders(Opts.IncludeSystemHeaders), PhonyTarget(Opts.UsePhonyTargets), AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), @@ -411,6 +413,11 @@ return; } + // Add extra dependencies to the end of the list. + for (auto ExtraDep : ExtraDeps) { + AddFilename(ExtraDep); + } + // Write out the dependency targets, trying to avoid overly long // lines when possible. We try our best to emit exactly the same // dependency file as GCC (4.2), assuming the included files are the Index: test/Frontend/dependency-gen.c =================================================================== --- test/Frontend/dependency-gen.c +++ test/Frontend/dependency-gen.c @@ -20,7 +20,16 @@ // RUN: cd a/b // RUN: %clang -MD -MF - %s -fsyntax-only -I ./ | FileCheck -check-prefix=CHECK-SIX %s // CHECK-SIX: {{ }}x.h - +// RUN: echo "fun:foo" > %t.blacklist +// RUN: %clang -MD -MF - %s -fsyntax-only -fsanitize=cfi-vcall -flto -fsanitize-blacklist=%t.blacklist -I ./ | FileCheck -check-prefix=CHECK-SEVEN %s +// CHECK-SEVEN: {{ }}x.h +// CHECK-SEVEN: .blacklist +// RUN: %clang -MD -MF - %s -fsyntax-only -fsanitize=address -flto -I . | FileCheck -check-prefix=CHECK-EIGHT %s +// CHECK-EIGHT: {{ }}x.h +// CHECK-EIGHT: asan_blacklist.txt +// RUN: %clang -MD -MF - %s -fsyntax-only -fsanitize=address -flto -I . -fno-sanitize-blacklist | FileCheck -check-prefix=CHECK-NINE %s +// CHECK-NINE: {{ }}x.h +// CHECK-NINE-NOT: asan_blacklist.txt #ifndef INCLUDE_FLAG_TEST #include #endif