]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp
Merge ^/head r318658 through r318963.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Driver / SanitizerArgs.cpp
1 //===--- SanitizerArgs.cpp - Arguments for sanitizer tools  ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include "clang/Driver/SanitizerArgs.h"
10 #include "ToolChains/CommonArgs.h"
11 #include "clang/Basic/Sanitizers.h"
12 #include "clang/Driver/Driver.h"
13 #include "clang/Driver/DriverDiagnostic.h"
14 #include "clang/Driver/Options.h"
15 #include "clang/Driver/ToolChain.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/SpecialCaseList.h"
21 #include <memory>
22
23 using namespace clang;
24 using namespace clang::SanitizerKind;
25 using namespace clang::driver;
26 using namespace llvm::opt;
27
28 enum : SanitizerMask {
29   NeedsUbsanRt = Undefined | Integer | Nullability | CFI,
30   NeedsUbsanCxxRt = Vptr | CFI,
31   NotAllowedWithTrap = Vptr,
32   RequiresPIE = DataFlow,
33   NeedsUnwindTables = Address | Thread | Memory | DataFlow,
34   SupportsCoverage =
35       Address | Memory | Leak | Undefined | Integer | Nullability | DataFlow,
36   RecoverableByDefault = Undefined | Integer | Nullability,
37   Unrecoverable = Unreachable | Return,
38   LegacyFsanitizeRecoverMask = Undefined | Integer,
39   NeedsLTO = CFI,
40   TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow |
41                       Nullability | LocalBounds | CFI,
42   TrappingDefault = CFI,
43   CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
44 };
45
46 enum CoverageFeature {
47   CoverageFunc = 1 << 0,
48   CoverageBB = 1 << 1,
49   CoverageEdge = 1 << 2,
50   CoverageIndirCall = 1 << 3,
51   CoverageTraceBB = 1 << 4,
52   CoverageTraceCmp = 1 << 5,
53   CoverageTraceDiv = 1 << 6,
54   CoverageTraceGep = 1 << 7,
55   Coverage8bitCounters = 1 << 8,
56   CoverageTracePC = 1 << 9,
57   CoverageTracePCGuard = 1 << 10,
58   CoverageNoPrune = 1 << 11,
59 };
60
61 /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
62 /// invalid components. Returns a SanitizerMask.
63 static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
64                                     bool DiagnoseErrors);
65
66 /// Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid
67 /// components. Returns OR of members of \c CoverageFeature enumeration.
68 static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A);
69
70 /// Produce an argument string from ArgList \p Args, which shows how it
71 /// provides some sanitizer kind from \p Mask. For example, the argument list
72 /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
73 /// would produce "-fsanitize=vptr".
74 static std::string lastArgumentForMask(const Driver &D,
75                                        const llvm::opt::ArgList &Args,
76                                        SanitizerMask Mask);
77
78 /// Produce an argument string from argument \p A, which shows how it provides
79 /// a value in \p Mask. For instance, the argument
80 /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
81 /// "-fsanitize=alignment".
82 static std::string describeSanitizeArg(const llvm::opt::Arg *A,
83                                        SanitizerMask Mask);
84
85 /// Produce a string containing comma-separated names of sanitizers in \p
86 /// Sanitizers set.
87 static std::string toString(const clang::SanitizerSet &Sanitizers);
88
89 static bool getDefaultBlacklist(const Driver &D, SanitizerMask Kinds,
90                                 std::string &BLPath) {
91   const char *BlacklistFile = nullptr;
92   if (Kinds & Address)
93     BlacklistFile = "asan_blacklist.txt";
94   else if (Kinds & Memory)
95     BlacklistFile = "msan_blacklist.txt";
96   else if (Kinds & Thread)
97     BlacklistFile = "tsan_blacklist.txt";
98   else if (Kinds & DataFlow)
99     BlacklistFile = "dfsan_abilist.txt";
100   else if (Kinds & CFI)
101     BlacklistFile = "cfi_blacklist.txt";
102
103   if (BlacklistFile) {
104     clang::SmallString<64> Path(D.ResourceDir);
105     llvm::sys::path::append(Path, BlacklistFile);
106     BLPath = Path.str();
107     return true;
108   }
109   return false;
110 }
111
112 /// Sets group bits for every group that has at least one representative already
113 /// enabled in \p Kinds.
114 static SanitizerMask setGroupBits(SanitizerMask Kinds) {
115 #define SANITIZER(NAME, ID)
116 #define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
117   if (Kinds & SanitizerKind::ID)                                               \
118     Kinds |= SanitizerKind::ID##Group;
119 #include "clang/Basic/Sanitizers.def"
120   return Kinds;
121 }
122
123 static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
124                                            const llvm::opt::ArgList &Args) {
125   SanitizerMask TrapRemove = 0; // During the loop below, the accumulated set of
126                                 // sanitizers disabled by the current sanitizer
127                                 // argument or any argument after it.
128   SanitizerMask TrappingKinds = 0;
129   SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported);
130
131   for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
132        I != E; ++I) {
133     const auto *Arg = *I;
134     if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
135       Arg->claim();
136       SanitizerMask Add = parseArgValues(D, Arg, true);
137       Add &= ~TrapRemove;
138       if (SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) {
139         SanitizerSet S;
140         S.Mask = InvalidValues;
141         D.Diag(diag::err_drv_unsupported_option_argument) << "-fsanitize-trap"
142                                                           << toString(S);
143       }
144       TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove;
145     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
146       Arg->claim();
147       TrapRemove |= expandSanitizerGroups(parseArgValues(D, Arg, true));
148     } else if (Arg->getOption().matches(
149                    options::OPT_fsanitize_undefined_trap_on_error)) {
150       Arg->claim();
151       TrappingKinds |=
152           expandSanitizerGroups(UndefinedGroup & ~TrapRemove) & ~TrapRemove;
153     } else if (Arg->getOption().matches(
154                    options::OPT_fno_sanitize_undefined_trap_on_error)) {
155       Arg->claim();
156       TrapRemove |= expandSanitizerGroups(UndefinedGroup);
157     }
158   }
159
160   // Apply default trapping behavior.
161   TrappingKinds |= TrappingDefault & ~TrapRemove;
162
163   return TrappingKinds;
164 }
165
166 bool SanitizerArgs::needsUbsanRt() const {
167   return ((Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
168           CoverageFeatures) &&
169          !Sanitizers.has(Address) && !Sanitizers.has(Memory) &&
170          !Sanitizers.has(Thread) && !Sanitizers.has(DataFlow) && 
171          !Sanitizers.has(Leak) && !CfiCrossDso;
172 }
173
174 bool SanitizerArgs::needsCfiRt() const {
175   return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso;
176 }
177
178 bool SanitizerArgs::needsCfiDiagRt() const {
179   return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso;
180 }
181
182 bool SanitizerArgs::requiresPIE() const {
183   return NeedPIE || (Sanitizers.Mask & RequiresPIE);
184 }
185
186 bool SanitizerArgs::needsUnwindTables() const {
187   return Sanitizers.Mask & NeedsUnwindTables;
188 }
189
190 SanitizerArgs::SanitizerArgs(const ToolChain &TC,
191                              const llvm::opt::ArgList &Args) {
192   SanitizerMask AllRemove = 0;  // During the loop below, the accumulated set of
193                                 // sanitizers disabled by the current sanitizer
194                                 // argument or any argument after it.
195   SanitizerMask AllAddedKinds = 0;  // Mask of all sanitizers ever enabled by
196                                     // -fsanitize= flags (directly or via group
197                                     // expansion), some of which may be disabled
198                                     // later. Used to carefully prune
199                                     // unused-argument diagnostics.
200   SanitizerMask DiagnosedKinds = 0;  // All Kinds we have diagnosed up to now.
201                                      // Used to deduplicate diagnostics.
202   SanitizerMask Kinds = 0;
203   const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
204   ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
205
206   const Driver &D = TC.getDriver();
207   SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
208   SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
209
210   for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
211        I != E; ++I) {
212     const auto *Arg = *I;
213     if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
214       Arg->claim();
215       SanitizerMask Add = parseArgValues(D, Arg, true);
216       AllAddedKinds |= expandSanitizerGroups(Add);
217
218       // Avoid diagnosing any sanitizer which is disabled later.
219       Add &= ~AllRemove;
220       // At this point we have not expanded groups, so any unsupported
221       // sanitizers in Add are those which have been explicitly enabled.
222       // Diagnose them.
223       if (SanitizerMask KindsToDiagnose =
224               Add & InvalidTrappingKinds & ~DiagnosedKinds) {
225         std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
226         D.Diag(diag::err_drv_argument_not_allowed_with)
227             << Desc << "-fsanitize-trap=undefined";
228         DiagnosedKinds |= KindsToDiagnose;
229       }
230       Add &= ~InvalidTrappingKinds;
231       if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
232         std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
233         D.Diag(diag::err_drv_unsupported_opt_for_target)
234             << Desc << TC.getTriple().str();
235         DiagnosedKinds |= KindsToDiagnose;
236       }
237       Add &= Supported;
238
239       // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
240       // so we don't error out if -fno-rtti and -fsanitize=undefined were
241       // passed.
242       if (Add & Vptr &&
243           (RTTIMode == ToolChain::RM_DisabledImplicitly ||
244            RTTIMode == ToolChain::RM_DisabledExplicitly)) {
245         if (RTTIMode == ToolChain::RM_DisabledImplicitly)
246           // Warn about not having rtti enabled if the vptr sanitizer is
247           // explicitly enabled
248           D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
249         else {
250           const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg();
251           assert(NoRTTIArg &&
252                  "RTTI disabled explicitly but we have no argument!");
253           D.Diag(diag::err_drv_argument_not_allowed_with)
254               << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
255         }
256
257         // Take out the Vptr sanitizer from the enabled sanitizers
258         AllRemove |= Vptr;
259       }
260
261       Add = expandSanitizerGroups(Add);
262       // Group expansion may have enabled a sanitizer which is disabled later.
263       Add &= ~AllRemove;
264       // Silently discard any unsupported sanitizers implicitly enabled through
265       // group expansion.
266       Add &= ~InvalidTrappingKinds;
267       Add &= Supported;
268
269       // Enable coverage if the fuzzing flag is set.
270       if (Add & Fuzzer)
271         CoverageFeatures |= CoverageTracePCGuard | CoverageIndirCall | CoverageTraceCmp;
272
273       Kinds |= Add;
274     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
275       Arg->claim();
276       SanitizerMask Remove = parseArgValues(D, Arg, true);
277       AllRemove |= expandSanitizerGroups(Remove);
278     }
279   }
280
281   // Enable toolchain specific default sanitizers if not explicitly disabled.
282   Kinds |= TC.getDefaultSanitizers() & ~AllRemove;
283
284   // We disable the vptr sanitizer if it was enabled by group expansion but RTTI
285   // is disabled.
286   if ((Kinds & Vptr) &&
287       (RTTIMode == ToolChain::RM_DisabledImplicitly ||
288        RTTIMode == ToolChain::RM_DisabledExplicitly)) {
289     Kinds &= ~Vptr;
290   }
291
292   // Check that LTO is enabled if we need it.
293   if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {
294     D.Diag(diag::err_drv_argument_only_allowed_with)
295         << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
296   }
297
298   // Report error if there are non-trapping sanitizers that require
299   // c++abi-specific  parts of UBSan runtime, and they are not provided by the
300   // toolchain. We don't have a good way to check the latter, so we just
301   // check if the toolchan supports vptr.
302   if (~Supported & Vptr) {
303     SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
304     // The runtime library supports the Microsoft C++ ABI, but only well enough
305     // for CFI. FIXME: Remove this once we support vptr on Windows.
306     if (TC.getTriple().isOSWindows())
307       KindsToDiagnose &= ~CFI;
308     if (KindsToDiagnose) {
309       SanitizerSet S;
310       S.Mask = KindsToDiagnose;
311       D.Diag(diag::err_drv_unsupported_opt_for_target)
312           << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str();
313       Kinds &= ~KindsToDiagnose;
314     }
315   }
316
317   // Warn about incompatible groups of sanitizers.
318   std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
319       std::make_pair(Address, Thread), std::make_pair(Address, Memory),
320       std::make_pair(Thread, Memory), std::make_pair(Leak, Thread),
321       std::make_pair(Leak, Memory), std::make_pair(KernelAddress, Address),
322       std::make_pair(KernelAddress, Leak),
323       std::make_pair(KernelAddress, Thread),
324       std::make_pair(KernelAddress, Memory),
325       std::make_pair(Efficiency, Address),
326       std::make_pair(Efficiency, Leak),
327       std::make_pair(Efficiency, Thread),
328       std::make_pair(Efficiency, Memory),
329       std::make_pair(Efficiency, KernelAddress)};
330   for (auto G : IncompatibleGroups) {
331     SanitizerMask Group = G.first;
332     if (Kinds & Group) {
333       if (SanitizerMask Incompatible = Kinds & G.second) {
334         D.Diag(clang::diag::err_drv_argument_not_allowed_with)
335             << lastArgumentForMask(D, Args, Group)
336             << lastArgumentForMask(D, Args, Incompatible);
337         Kinds &= ~Incompatible;
338       }
339     }
340   }
341   // FIXME: Currently -fsanitize=leak is silently ignored in the presence of
342   // -fsanitize=address. Perhaps it should print an error, or perhaps
343   // -f(-no)sanitize=leak should change whether leak detection is enabled by
344   // default in ASan?
345
346   // Parse -f(no-)?sanitize-recover flags.
347   SanitizerMask RecoverableKinds = RecoverableByDefault;
348   SanitizerMask DiagnosedUnrecoverableKinds = 0;
349   for (const auto *Arg : Args) {
350     const char *DeprecatedReplacement = nullptr;
351     if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
352       DeprecatedReplacement =
353           "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all";
354       RecoverableKinds |= expandSanitizerGroups(LegacyFsanitizeRecoverMask);
355       Arg->claim();
356     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
357       DeprecatedReplacement = "-fno-sanitize-recover=undefined,integer' or "
358                               "'-fno-sanitize-recover=all";
359       RecoverableKinds &= ~expandSanitizerGroups(LegacyFsanitizeRecoverMask);
360       Arg->claim();
361     } else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
362       SanitizerMask Add = parseArgValues(D, Arg, true);
363       // Report error if user explicitly tries to recover from unrecoverable
364       // sanitizer.
365       if (SanitizerMask KindsToDiagnose =
366               Add & Unrecoverable & ~DiagnosedUnrecoverableKinds) {
367         SanitizerSet SetToDiagnose;
368         SetToDiagnose.Mask |= KindsToDiagnose;
369         D.Diag(diag::err_drv_unsupported_option_argument)
370             << Arg->getOption().getName() << toString(SetToDiagnose);
371         DiagnosedUnrecoverableKinds |= KindsToDiagnose;
372       }
373       RecoverableKinds |= expandSanitizerGroups(Add);
374       Arg->claim();
375     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
376       RecoverableKinds &= ~expandSanitizerGroups(parseArgValues(D, Arg, true));
377       Arg->claim();
378     }
379     if (DeprecatedReplacement) {
380       D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
381                                             << DeprecatedReplacement;
382     }
383   }
384   RecoverableKinds &= Kinds;
385   RecoverableKinds &= ~Unrecoverable;
386
387   TrappingKinds &= Kinds;
388
389   // Setup blacklist files.
390   // Add default blacklist from resource directory.
391   {
392     std::string BLPath;
393     if (getDefaultBlacklist(D, Kinds, BLPath) && llvm::sys::fs::exists(BLPath))
394       BlacklistFiles.push_back(BLPath);
395   }
396   // Parse -f(no-)sanitize-blacklist options.
397   for (const auto *Arg : Args) {
398     if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) {
399       Arg->claim();
400       std::string BLPath = Arg->getValue();
401       if (llvm::sys::fs::exists(BLPath)) {
402         BlacklistFiles.push_back(BLPath);
403         ExtraDeps.push_back(BLPath);
404       } else
405         D.Diag(clang::diag::err_drv_no_such_file) << BLPath;
406
407     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
408       Arg->claim();
409       BlacklistFiles.clear();
410       ExtraDeps.clear();
411     }
412   }
413   // Validate blacklists format.
414   {
415     std::string BLError;
416     std::unique_ptr<llvm::SpecialCaseList> SCL(
417         llvm::SpecialCaseList::create(BlacklistFiles, BLError));
418     if (!SCL.get())
419       D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
420   }
421
422   // Parse -f[no-]sanitize-memory-track-origins[=level] options.
423   if (AllAddedKinds & Memory) {
424     if (Arg *A =
425             Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
426                             options::OPT_fsanitize_memory_track_origins,
427                             options::OPT_fno_sanitize_memory_track_origins)) {
428       if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
429         MsanTrackOrigins = 2;
430       } else if (A->getOption().matches(
431                      options::OPT_fno_sanitize_memory_track_origins)) {
432         MsanTrackOrigins = 0;
433       } else {
434         StringRef S = A->getValue();
435         if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
436             MsanTrackOrigins > 2) {
437           D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
438         }
439       }
440     }
441     MsanUseAfterDtor =
442         Args.hasArg(options::OPT_fsanitize_memory_use_after_dtor);
443     NeedPIE |= !(TC.getTriple().isOSLinux() &&
444                  TC.getTriple().getArch() == llvm::Triple::x86_64);
445   }
446
447   if (AllAddedKinds & Thread) {
448     TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access,
449                                     options::OPT_fno_sanitize_thread_memory_access,
450                                     TsanMemoryAccess);
451     TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit,
452                                      options::OPT_fno_sanitize_thread_func_entry_exit,
453                                      TsanFuncEntryExit);
454     TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics,
455                                options::OPT_fno_sanitize_thread_atomics,
456                                TsanAtomics);
457   }
458
459   if (AllAddedKinds & CFI) {
460     CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
461                                options::OPT_fno_sanitize_cfi_cross_dso, false);
462     // Without PIE, external function address may resolve to a PLT record, which
463     // can not be verified by the target module.
464     NeedPIE |= CfiCrossDso;
465   }
466
467   Stats = Args.hasFlag(options::OPT_fsanitize_stats,
468                        options::OPT_fno_sanitize_stats, false);
469
470   // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
471   // enabled sanitizers.
472   for (const auto *Arg : Args) {
473     if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
474       int LegacySanitizeCoverage;
475       if (Arg->getNumValues() == 1 &&
476           !StringRef(Arg->getValue(0))
477                .getAsInteger(0, LegacySanitizeCoverage)) {
478         CoverageFeatures = 0;
479         Arg->claim();
480         if (LegacySanitizeCoverage != 0) {
481           D.Diag(diag::warn_drv_deprecated_arg)
482               << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard";
483         }
484         continue;
485       }
486       CoverageFeatures |= parseCoverageFeatures(D, Arg);
487
488       // Disable coverage and not claim the flags if there is at least one
489       // non-supporting sanitizer.
490       if (!(AllAddedKinds & ~setGroupBits(SupportsCoverage))) {
491         Arg->claim();
492       } else {
493         CoverageFeatures = 0;
494       }
495     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
496       Arg->claim();
497       CoverageFeatures &= ~parseCoverageFeatures(D, Arg);
498     }
499   }
500   // Choose at most one coverage type: function, bb, or edge.
501   if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageBB))
502     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
503         << "-fsanitize-coverage=func"
504         << "-fsanitize-coverage=bb";
505   if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageEdge))
506     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
507         << "-fsanitize-coverage=func"
508         << "-fsanitize-coverage=edge";
509   if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
510     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
511         << "-fsanitize-coverage=bb"
512         << "-fsanitize-coverage=edge";
513   // Basic block tracing and 8-bit counters require some type of coverage
514   // enabled.
515   if (CoverageFeatures & CoverageTraceBB)
516     D.Diag(clang::diag::warn_drv_deprecated_arg)
517         << "-fsanitize-coverage=trace-bb"
518         << "-fsanitize-coverage=trace-pc-guard";
519   if (CoverageFeatures & Coverage8bitCounters)
520     D.Diag(clang::diag::warn_drv_deprecated_arg)
521         << "-fsanitize-coverage=8bit-counters"
522         << "-fsanitize-coverage=trace-pc-guard";
523
524   int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
525   if ((CoverageFeatures & InsertionPointTypes) &&
526       !(CoverageFeatures &(CoverageTracePC | CoverageTracePCGuard))) {
527     D.Diag(clang::diag::warn_drv_deprecated_arg)
528         << "-fsanitize-coverage=[func|bb|edge]"
529         << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
530   }
531
532   // trace-pc w/o func/bb/edge implies edge.
533   if ((CoverageFeatures & (CoverageTracePC | CoverageTracePCGuard)) &&
534       !(CoverageFeatures & InsertionPointTypes))
535     CoverageFeatures |= CoverageEdge;
536
537   if (AllAddedKinds & Address) {
538     AsanSharedRuntime =
539         Args.hasArg(options::OPT_shared_libasan) || TC.getTriple().isAndroid();
540     NeedPIE |= TC.getTriple().isAndroid();
541     if (Arg *A =
542             Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
543         StringRef S = A->getValue();
544         // Legal values are 0 and 1, 2, but in future we may add more levels.
545         if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
546             AsanFieldPadding > 2) {
547           D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
548         }
549     }
550
551     if (Arg *WindowsDebugRTArg =
552             Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
553                             options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
554                             options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
555       switch (WindowsDebugRTArg->getOption().getID()) {
556       case options::OPT__SLASH_MTd:
557       case options::OPT__SLASH_MDd:
558       case options::OPT__SLASH_LDd:
559         D.Diag(clang::diag::err_drv_argument_not_allowed_with)
560             << WindowsDebugRTArg->getAsString(Args)
561             << lastArgumentForMask(D, Args, Address);
562         D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
563       }
564     }
565
566     AsanUseAfterScope = Args.hasFlag(
567         options::OPT_fsanitize_address_use_after_scope,
568         options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
569
570     // As a workaround for a bug in gold 2.26 and earlier, dead stripping of
571     // globals in ASan is disabled by default on ELF targets.
572     // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
573     AsanGlobalsDeadStripping =
574         !TC.getTriple().isOSBinFormatELF() ||
575         Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
576   } else {
577     AsanUseAfterScope = false;
578   }
579
580   // Parse -link-cxx-sanitizer flag.
581   LinkCXXRuntimes =
582       Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.CCCIsCXX();
583
584   // Finally, initialize the set of available and recoverable sanitizers.
585   Sanitizers.Mask |= Kinds;
586   RecoverableSanitizers.Mask |= RecoverableKinds;
587   TrapSanitizers.Mask |= TrappingKinds;
588 }
589
590 static std::string toString(const clang::SanitizerSet &Sanitizers) {
591   std::string Res;
592 #define SANITIZER(NAME, ID)                                                    \
593   if (Sanitizers.has(ID)) {                                                    \
594     if (!Res.empty())                                                          \
595       Res += ",";                                                              \
596     Res += NAME;                                                               \
597   }
598 #include "clang/Basic/Sanitizers.def"
599   return Res;
600 }
601
602 static void addIncludeLinkerOption(const ToolChain &TC,
603                                    const llvm::opt::ArgList &Args,
604                                    llvm::opt::ArgStringList &CmdArgs,
605                                    StringRef SymbolName) {
606   SmallString<64> LinkerOptionFlag;
607   LinkerOptionFlag = "--linker-option=/include:";
608   if (TC.getTriple().getArch() == llvm::Triple::x86) {
609     // Win32 mangles C function names with a '_' prefix.
610     LinkerOptionFlag += '_';
611   }
612   LinkerOptionFlag += SymbolName;
613   CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
614 }
615
616 void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
617                             llvm::opt::ArgStringList &CmdArgs,
618                             types::ID InputType) const {
619   // NVPTX doesn't currently support sanitizers.  Bailing out here means that
620   // e.g. -fsanitize=address applies only to host code, which is what we want
621   // for now.
622   if (TC.getTriple().isNVPTX())
623     return;
624
625   // Translate available CoverageFeatures to corresponding clang-cc1 flags.
626   // Do it even if Sanitizers.empty() since some forms of coverage don't require
627   // sanitizers.
628   std::pair<int, const char *> CoverageFlags[] = {
629     std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
630     std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
631     std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
632     std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
633     std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
634     std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
635     std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
636     std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
637     std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
638     std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
639     std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"),
640     std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune")};
641   for (auto F : CoverageFlags) {
642     if (CoverageFeatures & F.first)
643       CmdArgs.push_back(F.second);
644   }
645
646   if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
647     // Instruct the code generator to embed linker directives in the object file
648     // that cause the required runtime libraries to be linked.
649     CmdArgs.push_back(Args.MakeArgString(
650         "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone")));
651     if (types::isCXX(InputType))
652       CmdArgs.push_back(Args.MakeArgString(
653           "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx")));
654   }
655   if (TC.getTriple().isOSWindows() && needsStatsRt()) {
656     CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" +
657                                          TC.getCompilerRT(Args, "stats_client")));
658
659     // The main executable must export the stats runtime.
660     // FIXME: Only exporting from the main executable (e.g. based on whether the
661     // translation unit defines main()) would save a little space, but having
662     // multiple copies of the runtime shouldn't hurt.
663     CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" +
664                                          TC.getCompilerRT(Args, "stats")));
665     addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
666   }
667
668   if (Sanitizers.empty())
669     return;
670   CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
671
672   if (!RecoverableSanitizers.empty())
673     CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
674                                          toString(RecoverableSanitizers)));
675
676   if (!TrapSanitizers.empty())
677     CmdArgs.push_back(
678         Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
679
680   for (const auto &BLPath : BlacklistFiles) {
681     SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
682     BlacklistOpt += BLPath;
683     CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
684   }
685   for (const auto &Dep : ExtraDeps) {
686     SmallString<64> ExtraDepOpt("-fdepfile-entry=");
687     ExtraDepOpt += Dep;
688     CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
689   }
690
691   if (MsanTrackOrigins)
692     CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
693                                          llvm::utostr(MsanTrackOrigins)));
694
695   if (MsanUseAfterDtor)
696     CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
697
698   // FIXME: Pass these parameters as function attributes, not as -llvm flags.
699   if (!TsanMemoryAccess) {
700     CmdArgs.push_back("-mllvm");
701     CmdArgs.push_back("-tsan-instrument-memory-accesses=0");
702     CmdArgs.push_back("-mllvm");
703     CmdArgs.push_back("-tsan-instrument-memintrinsics=0");
704   }
705   if (!TsanFuncEntryExit) {
706     CmdArgs.push_back("-mllvm");
707     CmdArgs.push_back("-tsan-instrument-func-entry-exit=0");
708   }
709   if (!TsanAtomics) {
710     CmdArgs.push_back("-mllvm");
711     CmdArgs.push_back("-tsan-instrument-atomics=0");
712   }
713
714   if (CfiCrossDso)
715     CmdArgs.push_back("-fsanitize-cfi-cross-dso");
716
717   if (Stats)
718     CmdArgs.push_back("-fsanitize-stats");
719
720   if (AsanFieldPadding)
721     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
722                                          llvm::utostr(AsanFieldPadding)));
723
724   if (AsanUseAfterScope)
725     CmdArgs.push_back("-fsanitize-address-use-after-scope");
726
727   if (AsanGlobalsDeadStripping)
728     CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
729
730   // MSan: Workaround for PR16386.
731   // ASan: This is mainly to help LSan with cases such as
732   // https://code.google.com/p/address-sanitizer/issues/detail?id=373
733   // We can't make this conditional on -fsanitize=leak, as that flag shouldn't
734   // affect compilation.
735   if (Sanitizers.has(Memory) || Sanitizers.has(Address))
736     CmdArgs.push_back("-fno-assume-sane-operator-new");
737
738   // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
739   // enabled.
740   if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
741       !Args.hasArg(options::OPT_fvisibility_EQ)) {
742     TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
743         << lastArgumentForMask(TC.getDriver(), Args,
744                                Sanitizers.Mask & CFIClasses)
745         << "-fvisibility=";
746   }
747 }
748
749 SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
750                              bool DiagnoseErrors) {
751   assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
752           A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
753           A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
754           A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
755           A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
756           A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
757          "Invalid argument in parseArgValues!");
758   SanitizerMask Kinds = 0;
759   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
760     const char *Value = A->getValue(i);
761     SanitizerMask Kind;
762     // Special case: don't accept -fsanitize=all.
763     if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
764         0 == strcmp("all", Value))
765       Kind = 0;
766     // Similarly, don't accept -fsanitize=efficiency-all.
767     else if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
768         0 == strcmp("efficiency-all", Value))
769       Kind = 0;
770     else
771       Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
772
773     if (Kind)
774       Kinds |= Kind;
775     else if (DiagnoseErrors)
776       D.Diag(clang::diag::err_drv_unsupported_option_argument)
777           << A->getOption().getName() << Value;
778   }
779   return Kinds;
780 }
781
782 int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
783   assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
784          A->getOption().matches(options::OPT_fno_sanitize_coverage));
785   int Features = 0;
786   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
787     const char *Value = A->getValue(i);
788     int F = llvm::StringSwitch<int>(Value)
789         .Case("func", CoverageFunc)
790         .Case("bb", CoverageBB)
791         .Case("edge", CoverageEdge)
792         .Case("indirect-calls", CoverageIndirCall)
793         .Case("trace-bb", CoverageTraceBB)
794         .Case("trace-cmp", CoverageTraceCmp)
795         .Case("trace-div", CoverageTraceDiv)
796         .Case("trace-gep", CoverageTraceGep)
797         .Case("8bit-counters", Coverage8bitCounters)
798         .Case("trace-pc", CoverageTracePC)
799         .Case("trace-pc-guard", CoverageTracePCGuard)
800         .Case("no-prune", CoverageNoPrune)
801         .Default(0);
802     if (F == 0)
803       D.Diag(clang::diag::err_drv_unsupported_option_argument)
804           << A->getOption().getName() << Value;
805     Features |= F;
806   }
807   return Features;
808 }
809
810 std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
811                                 SanitizerMask Mask) {
812   for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
813                                                   E = Args.rend();
814        I != E; ++I) {
815     const auto *Arg = *I;
816     if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
817       SanitizerMask AddKinds =
818           expandSanitizerGroups(parseArgValues(D, Arg, false));
819       if (AddKinds & Mask)
820         return describeSanitizeArg(Arg, Mask);
821     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
822       SanitizerMask RemoveKinds =
823           expandSanitizerGroups(parseArgValues(D, Arg, false));
824       Mask &= ~RemoveKinds;
825     }
826   }
827   llvm_unreachable("arg list didn't provide expected value");
828 }
829
830 std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
831   assert(A->getOption().matches(options::OPT_fsanitize_EQ)
832          && "Invalid argument in describeSanitizerArg!");
833
834   std::string Sanitizers;
835   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
836     if (expandSanitizerGroups(
837             parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
838         Mask) {
839       if (!Sanitizers.empty())
840         Sanitizers += ",";
841       Sanitizers += A->getValue(i);
842     }
843   }
844
845   assert(!Sanitizers.empty() && "arg didn't provide expected value");
846   return "-fsanitize=" + Sanitizers;
847 }