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