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