Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Driver/SanitizerArgs.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- SanitizerArgs.cpp - Arguments for sanitizer tools  ---------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
#include "clang/Driver/SanitizerArgs.h"
9
#include "ToolChains/CommonArgs.h"
10
#include "clang/Basic/Sanitizers.h"
11
#include "clang/Driver/Driver.h"
12
#include "clang/Driver/DriverDiagnostic.h"
13
#include "clang/Driver/Options.h"
14
#include "clang/Driver/ToolChain.h"
15
#include "llvm/ADT/StringExtras.h"
16
#include "llvm/ADT/StringRef.h"
17
#include "llvm/ADT/StringSwitch.h"
18
#include "llvm/Support/Path.h"
19
#include "llvm/Support/SpecialCaseList.h"
20
#include "llvm/Support/VirtualFileSystem.h"
21
#include "llvm/TargetParser/AArch64TargetParser.h"
22
#include "llvm/TargetParser/RISCVTargetParser.h"
23
#include "llvm/TargetParser/TargetParser.h"
24
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
25
#include <memory>
26
27
using namespace clang;
28
using namespace clang::driver;
29
using namespace llvm::opt;
30
31
static const SanitizerMask NeedsUbsanRt =
32
    SanitizerKind::Undefined | SanitizerKind::Integer |
33
    SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
34
    SanitizerKind::CFI | SanitizerKind::FloatDivideByZero |
35
    SanitizerKind::ObjCCast;
36
static const SanitizerMask NeedsUbsanCxxRt =
37
    SanitizerKind::Vptr | SanitizerKind::CFI;
38
static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
39
static const SanitizerMask NotAllowedWithMinimalRuntime = SanitizerKind::Vptr;
40
static const SanitizerMask NotAllowedWithExecuteOnly =
41
    SanitizerKind::Function | SanitizerKind::KCFI;
42
static const SanitizerMask NeedsUnwindTables =
43
    SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread |
44
    SanitizerKind::Memory | SanitizerKind::DataFlow;
45
static const SanitizerMask SupportsCoverage =
46
    SanitizerKind::Address | SanitizerKind::HWAddress |
47
    SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
48
    SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap |
49
    SanitizerKind::MemtagGlobals | SanitizerKind::Memory |
50
    SanitizerKind::KernelMemory | SanitizerKind::Leak |
51
    SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::Bounds |
52
    SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
53
    SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
54
    SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero |
55
    SanitizerKind::SafeStack | SanitizerKind::ShadowCallStack |
56
    SanitizerKind::Thread | SanitizerKind::ObjCCast | SanitizerKind::KCFI;
57
static const SanitizerMask RecoverableByDefault =
58
    SanitizerKind::Undefined | SanitizerKind::Integer |
59
    SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
60
    SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
61
static const SanitizerMask Unrecoverable =
62
    SanitizerKind::Unreachable | SanitizerKind::Return;
63
static const SanitizerMask AlwaysRecoverable = SanitizerKind::KernelAddress |
64
                                               SanitizerKind::KernelHWAddress |
65
                                               SanitizerKind::KCFI;
66
static const SanitizerMask NeedsLTO = SanitizerKind::CFI;
67
static const SanitizerMask TrappingSupported =
68
    (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | SanitizerKind::Integer |
69
    SanitizerKind::Nullability | SanitizerKind::LocalBounds |
70
    SanitizerKind::CFI | SanitizerKind::FloatDivideByZero |
71
    SanitizerKind::ObjCCast;
72
static const SanitizerMask TrappingDefault = SanitizerKind::CFI;
73
static const SanitizerMask CFIClasses =
74
    SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
75
    SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
76
    SanitizerKind::CFIUnrelatedCast;
77
static const SanitizerMask CompatibleWithMinimalRuntime =
78
    TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack |
79
    SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap |
80
    SanitizerKind::MemtagGlobals | SanitizerKind::KCFI;
81
82
enum CoverageFeature {
83
  CoverageFunc = 1 << 0,
84
  CoverageBB = 1 << 1,
85
  CoverageEdge = 1 << 2,
86
  CoverageIndirCall = 1 << 3,
87
  CoverageTraceBB = 1 << 4, // Deprecated.
88
  CoverageTraceCmp = 1 << 5,
89
  CoverageTraceDiv = 1 << 6,
90
  CoverageTraceGep = 1 << 7,
91
  Coverage8bitCounters = 1 << 8, // Deprecated.
92
  CoverageTracePC = 1 << 9,
93
  CoverageTracePCGuard = 1 << 10,
94
  CoverageNoPrune = 1 << 11,
95
  CoverageInline8bitCounters = 1 << 12,
96
  CoveragePCTable = 1 << 13,
97
  CoverageStackDepth = 1 << 14,
98
  CoverageInlineBoolFlag = 1 << 15,
99
  CoverageTraceLoads = 1 << 16,
100
  CoverageTraceStores = 1 << 17,
101
  CoverageControlFlow = 1 << 18,
102
};
103
104
enum BinaryMetadataFeature {
105
  BinaryMetadataCovered = 1 << 0,
106
  BinaryMetadataAtomics = 1 << 1,
107
  BinaryMetadataUAR = 1 << 2,
108
};
109
110
/// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
111
/// invalid components. Returns a SanitizerMask.
112
static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
113
                                    bool DiagnoseErrors);
114
115
/// Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid
116
/// components. Returns OR of members of \c CoverageFeature enumeration.
117
static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A,
118
                                 bool DiagnoseErrors);
119
120
/// Parse -f(no-)?sanitize-metadata= flag values, diagnosing any invalid
121
/// components. Returns OR of members of \c BinaryMetadataFeature enumeration.
122
static int parseBinaryMetadataFeatures(const Driver &D, const llvm::opt::Arg *A,
123
                                       bool DiagnoseErrors);
124
125
/// Produce an argument string from ArgList \p Args, which shows how it
126
/// provides some sanitizer kind from \p Mask. For example, the argument list
127
/// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
128
/// would produce "-fsanitize=vptr".
129
static std::string lastArgumentForMask(const Driver &D,
130
                                       const llvm::opt::ArgList &Args,
131
                                       SanitizerMask Mask);
132
133
/// Produce an argument string from argument \p A, which shows how it provides
134
/// a value in \p Mask. For instance, the argument
135
/// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
136
/// "-fsanitize=alignment".
137
static std::string describeSanitizeArg(const llvm::opt::Arg *A,
138
                                       SanitizerMask Mask);
139
140
/// Produce a string containing comma-separated names of sanitizers in \p
141
/// Sanitizers set.
142
static std::string toString(const clang::SanitizerSet &Sanitizers);
143
144
/// Return true if an execute-only target disallows data access to code
145
/// sections.
146
static bool isExecuteOnlyTarget(const llvm::Triple &Triple,
147
0
                                const llvm::opt::ArgList &Args) {
148
0
  if (Triple.isPS5())
149
0
    return true;
150
0
  return Args.hasFlagNoClaim(options::OPT_mexecute_only,
151
0
                             options::OPT_mno_execute_only, false);
152
0
}
153
154
static void validateSpecialCaseListFormat(const Driver &D,
155
                                          std::vector<std::string> &SCLFiles,
156
                                          unsigned MalformedSCLErrorDiagID,
157
0
                                          bool DiagnoseErrors) {
158
0
  if (SCLFiles.empty())
159
0
    return;
160
161
0
  std::string BLError;
162
0
  std::unique_ptr<llvm::SpecialCaseList> SCL(
163
0
      llvm::SpecialCaseList::create(SCLFiles, D.getVFS(), BLError));
164
0
  if (!SCL.get() && DiagnoseErrors)
165
0
    D.Diag(MalformedSCLErrorDiagID) << BLError;
166
0
}
167
168
static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds,
169
                                  std::vector<std::string> &IgnorelistFiles,
170
0
                                  bool DiagnoseErrors) {
171
0
  struct Ignorelist {
172
0
    const char *File;
173
0
    SanitizerMask Mask;
174
0
  } Ignorelists[] = {{"asan_ignorelist.txt", SanitizerKind::Address},
175
0
                     {"hwasan_ignorelist.txt", SanitizerKind::HWAddress},
176
0
                     {"memtag_ignorelist.txt", SanitizerKind::MemTag},
177
0
                     {"msan_ignorelist.txt", SanitizerKind::Memory},
178
0
                     {"tsan_ignorelist.txt", SanitizerKind::Thread},
179
0
                     {"dfsan_abilist.txt", SanitizerKind::DataFlow},
180
0
                     {"cfi_ignorelist.txt", SanitizerKind::CFI},
181
0
                     {"ubsan_ignorelist.txt",
182
0
                      SanitizerKind::Undefined | SanitizerKind::Integer |
183
0
                          SanitizerKind::Nullability |
184
0
                          SanitizerKind::FloatDivideByZero}};
185
186
0
  for (auto BL : Ignorelists) {
187
0
    if (!(Kinds & BL.Mask))
188
0
      continue;
189
190
0
    clang::SmallString<64> Path(D.ResourceDir);
191
0
    llvm::sys::path::append(Path, "share", BL.File);
192
0
    if (D.getVFS().exists(Path))
193
0
      IgnorelistFiles.push_back(std::string(Path.str()));
194
0
    else if (BL.Mask == SanitizerKind::CFI && DiagnoseErrors)
195
      // If cfi_ignorelist.txt cannot be found in the resource dir, driver
196
      // should fail.
197
0
      D.Diag(clang::diag::err_drv_missing_sanitizer_ignorelist) << Path;
198
0
  }
199
0
  validateSpecialCaseListFormat(
200
0
      D, IgnorelistFiles, clang::diag::err_drv_malformed_sanitizer_ignorelist,
201
0
      DiagnoseErrors);
202
0
}
203
204
/// Parse -f(no-)?sanitize-(coverage-)?(allow|ignore)list argument's values,
205
/// diagnosing any invalid file paths and validating special case list format.
206
static void parseSpecialCaseListArg(const Driver &D,
207
                                    const llvm::opt::ArgList &Args,
208
                                    std::vector<std::string> &SCLFiles,
209
                                    llvm::opt::OptSpecifier SCLOptionID,
210
                                    llvm::opt::OptSpecifier NoSCLOptionID,
211
                                    unsigned MalformedSCLErrorDiagID,
212
0
                                    bool DiagnoseErrors) {
213
0
  for (const auto *Arg : Args) {
214
    // Match -fsanitize-(coverage-)?(allow|ignore)list.
215
0
    if (Arg->getOption().matches(SCLOptionID)) {
216
0
      Arg->claim();
217
0
      std::string SCLPath = Arg->getValue();
218
0
      if (D.getVFS().exists(SCLPath)) {
219
0
        SCLFiles.push_back(SCLPath);
220
0
      } else if (DiagnoseErrors) {
221
0
        D.Diag(clang::diag::err_drv_no_such_file) << SCLPath;
222
0
      }
223
      // Match -fno-sanitize-ignorelist.
224
0
    } else if (Arg->getOption().matches(NoSCLOptionID)) {
225
0
      Arg->claim();
226
0
      SCLFiles.clear();
227
0
    }
228
0
  }
229
0
  validateSpecialCaseListFormat(D, SCLFiles, MalformedSCLErrorDiagID,
230
0
                                DiagnoseErrors);
231
0
}
232
233
/// Sets group bits for every group that has at least one representative already
234
/// enabled in \p Kinds.
235
0
static SanitizerMask setGroupBits(SanitizerMask Kinds) {
236
0
#define SANITIZER(NAME, ID)
237
0
#define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
238
0
  if (Kinds & SanitizerKind::ID)                                               \
239
0
    Kinds |= SanitizerKind::ID##Group;
240
0
#include "clang/Basic/Sanitizers.def"
241
0
  return Kinds;
242
0
}
243
244
static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
245
                                           const llvm::opt::ArgList &Args,
246
0
                                           bool DiagnoseErrors) {
247
0
  SanitizerMask TrapRemove; // During the loop below, the accumulated set of
248
                            // sanitizers disabled by the current sanitizer
249
                            // argument or any argument after it.
250
0
  SanitizerMask TrappingKinds;
251
0
  SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported);
252
253
0
  for (const llvm::opt::Arg *Arg : llvm::reverse(Args)) {
254
0
    if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
255
0
      Arg->claim();
256
0
      SanitizerMask Add = parseArgValues(D, Arg, true);
257
0
      Add &= ~TrapRemove;
258
0
      SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups;
259
0
      if (InvalidValues && DiagnoseErrors) {
260
0
        SanitizerSet S;
261
0
        S.Mask = InvalidValues;
262
0
        D.Diag(diag::err_drv_unsupported_option_argument)
263
0
            << Arg->getSpelling() << toString(S);
264
0
      }
265
0
      TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove;
266
0
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
267
0
      Arg->claim();
268
0
      TrapRemove |=
269
0
          expandSanitizerGroups(parseArgValues(D, Arg, DiagnoseErrors));
270
0
    }
271
0
  }
272
273
  // Apply default trapping behavior.
274
0
  TrappingKinds |= TrappingDefault & ~TrapRemove;
275
276
0
  return TrappingKinds;
277
0
}
278
279
0
bool SanitizerArgs::needsFuzzerInterceptors() const {
280
0
  return needsFuzzer() && !needsAsanRt() && !needsTsanRt() && !needsMsanRt();
281
0
}
282
283
0
bool SanitizerArgs::needsUbsanRt() const {
284
  // All of these include ubsan.
285
0
  if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
286
0
      needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
287
0
      (needsScudoRt() && !requiresMinimalRuntime()))
288
0
    return false;
289
290
0
  return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
291
0
         CoverageFeatures;
292
0
}
293
294
0
bool SanitizerArgs::needsCfiRt() const {
295
0
  return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
296
0
         CfiCrossDso && !ImplicitCfiRuntime;
297
0
}
298
299
0
bool SanitizerArgs::needsCfiDiagRt() const {
300
0
  return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
301
0
         CfiCrossDso && !ImplicitCfiRuntime;
302
0
}
303
304
0
bool SanitizerArgs::requiresPIE() const { return NeedPIE; }
305
306
0
bool SanitizerArgs::needsUnwindTables() const {
307
0
  return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables);
308
0
}
309
310
0
bool SanitizerArgs::needsLTO() const {
311
0
  return static_cast<bool>(Sanitizers.Mask & NeedsLTO);
312
0
}
313
314
SanitizerArgs::SanitizerArgs(const ToolChain &TC,
315
                             const llvm::opt::ArgList &Args,
316
0
                             bool DiagnoseErrors) {
317
0
  SanitizerMask AllRemove;      // During the loop below, the accumulated set of
318
                                // sanitizers disabled by the current sanitizer
319
                                // argument or any argument after it.
320
0
  SanitizerMask AllAddedKinds;  // Mask of all sanitizers ever enabled by
321
                                // -fsanitize= flags (directly or via group
322
                                // expansion), some of which may be disabled
323
                                // later. Used to carefully prune
324
                                // unused-argument diagnostics.
325
0
  SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now.
326
                                // Used to deduplicate diagnostics.
327
0
  SanitizerMask Kinds;
328
0
  const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
329
330
0
  CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
331
0
                             options::OPT_fno_sanitize_cfi_cross_dso, false);
332
333
0
  ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
334
335
0
  const Driver &D = TC.getDriver();
336
0
  SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args, DiagnoseErrors);
337
0
  SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
338
339
0
  MinimalRuntime =
340
0
      Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
341
0
                   options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
342
343
  // The object size sanitizer should not be enabled at -O0.
344
0
  Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
345
0
  bool RemoveObjectSizeAtO0 =
346
0
      !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
347
348
0
  for (const llvm::opt::Arg *Arg : llvm::reverse(Args)) {
349
0
    if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
350
0
      Arg->claim();
351
0
      SanitizerMask Add = parseArgValues(D, Arg, DiagnoseErrors);
352
353
0
      if (RemoveObjectSizeAtO0) {
354
0
        AllRemove |= SanitizerKind::ObjectSize;
355
356
        // The user explicitly enabled the object size sanitizer. Warn
357
        // that this does nothing at -O0.
358
0
        if ((Add & SanitizerKind::ObjectSize) && DiagnoseErrors)
359
0
          D.Diag(diag::warn_drv_object_size_disabled_O0)
360
0
              << Arg->getAsString(Args);
361
0
      }
362
363
0
      AllAddedKinds |= expandSanitizerGroups(Add);
364
365
      // Avoid diagnosing any sanitizer which is disabled later.
366
0
      Add &= ~AllRemove;
367
      // At this point we have not expanded groups, so any unsupported
368
      // sanitizers in Add are those which have been explicitly enabled.
369
      // Diagnose them.
370
0
      if (SanitizerMask KindsToDiagnose =
371
0
              Add & InvalidTrappingKinds & ~DiagnosedKinds) {
372
0
        if (DiagnoseErrors) {
373
0
          std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
374
0
          D.Diag(diag::err_drv_argument_not_allowed_with)
375
0
              << Desc << "-fsanitize-trap=undefined";
376
0
        }
377
0
        DiagnosedKinds |= KindsToDiagnose;
378
0
      }
379
0
      Add &= ~InvalidTrappingKinds;
380
381
0
      if (MinimalRuntime) {
382
0
        if (SanitizerMask KindsToDiagnose =
383
0
                Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) {
384
0
          if (DiagnoseErrors) {
385
0
            std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
386
0
            D.Diag(diag::err_drv_argument_not_allowed_with)
387
0
                << Desc << "-fsanitize-minimal-runtime";
388
0
          }
389
0
          DiagnosedKinds |= KindsToDiagnose;
390
0
        }
391
0
        Add &= ~NotAllowedWithMinimalRuntime;
392
0
      }
393
394
0
      if (llvm::opt::Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
395
0
        StringRef CM = A->getValue();
396
0
        if (CM != "small" &&
397
0
            (Add & SanitizerKind::Function & ~DiagnosedKinds)) {
398
0
          if (DiagnoseErrors)
399
0
            D.Diag(diag::err_drv_argument_only_allowed_with)
400
0
                << "-fsanitize=function"
401
0
                << "-mcmodel=small";
402
0
          Add &= ~SanitizerKind::Function;
403
0
          DiagnosedKinds |= SanitizerKind::Function;
404
0
        }
405
0
      }
406
      // -fsanitize=function and -fsanitize=kcfi instrument indirect function
407
      // calls to load a type hash before the function label. Therefore, an
408
      // execute-only target doesn't support the function and kcfi sanitizers.
409
0
      const llvm::Triple &Triple = TC.getTriple();
410
0
      if (isExecuteOnlyTarget(Triple, Args)) {
411
0
        if (SanitizerMask KindsToDiagnose =
412
0
                Add & NotAllowedWithExecuteOnly & ~DiagnosedKinds) {
413
0
          if (DiagnoseErrors) {
414
0
            std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
415
0
            D.Diag(diag::err_drv_argument_not_allowed_with)
416
0
                << Desc << Triple.str();
417
0
          }
418
0
          DiagnosedKinds |= KindsToDiagnose;
419
0
        }
420
0
        Add &= ~NotAllowedWithExecuteOnly;
421
0
      }
422
423
      // FIXME: Make CFI on member function calls compatible with cross-DSO CFI.
424
      // There are currently two problems:
425
      // - Virtual function call checks need to pass a pointer to the function
426
      //   address to llvm.type.test and a pointer to the address point to the
427
      //   diagnostic function. Currently we pass the same pointer to both
428
      //   places.
429
      // - Non-virtual function call checks may need to check multiple type
430
      //   identifiers.
431
      // Fixing both of those may require changes to the cross-DSO CFI
432
      // interface.
433
0
      if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) {
434
0
        if (DiagnoseErrors)
435
0
          D.Diag(diag::err_drv_argument_not_allowed_with)
436
0
              << "-fsanitize=cfi-mfcall"
437
0
              << "-fsanitize-cfi-cross-dso";
438
0
        Add &= ~SanitizerKind::CFIMFCall;
439
0
        DiagnosedKinds |= SanitizerKind::CFIMFCall;
440
0
      }
441
442
0
      if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
443
0
        if (DiagnoseErrors) {
444
0
          std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
445
0
          D.Diag(diag::err_drv_unsupported_opt_for_target)
446
0
              << Desc << TC.getTriple().str();
447
0
        }
448
0
        DiagnosedKinds |= KindsToDiagnose;
449
0
      }
450
0
      Add &= Supported;
451
452
      // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
453
      // so we don't error out if -fno-rtti and -fsanitize=undefined were
454
      // passed.
455
0
      if ((Add & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
456
0
        if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) {
457
0
          assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
458
0
                 "RTTI disabled without -fno-rtti option?");
459
          // The user explicitly passed -fno-rtti with -fsanitize=vptr, but
460
          // the vptr sanitizer requires RTTI, so this is a user error.
461
0
          if (DiagnoseErrors)
462
0
            D.Diag(diag::err_drv_argument_not_allowed_with)
463
0
                << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
464
0
        } else {
465
          // The vptr sanitizer requires RTTI, but RTTI is disabled (by
466
          // default). Warn that the vptr sanitizer is being disabled.
467
0
          if (DiagnoseErrors)
468
0
            D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
469
0
        }
470
471
        // Take out the Vptr sanitizer from the enabled sanitizers
472
0
        AllRemove |= SanitizerKind::Vptr;
473
0
      }
474
475
0
      Add = expandSanitizerGroups(Add);
476
      // Group expansion may have enabled a sanitizer which is disabled later.
477
0
      Add &= ~AllRemove;
478
      // Silently discard any unsupported sanitizers implicitly enabled through
479
      // group expansion.
480
0
      Add &= ~InvalidTrappingKinds;
481
0
      if (MinimalRuntime) {
482
0
        Add &= ~NotAllowedWithMinimalRuntime;
483
0
      }
484
      // NotAllowedWithExecuteOnly is silently discarded on an execute-only
485
      // target if implicitly enabled through group expansion.
486
0
      if (isExecuteOnlyTarget(Triple, Args))
487
0
        Add &= ~NotAllowedWithExecuteOnly;
488
0
      if (CfiCrossDso)
489
0
        Add &= ~SanitizerKind::CFIMFCall;
490
0
      Add &= Supported;
491
492
0
      if (Add & SanitizerKind::Fuzzer)
493
0
        Add |= SanitizerKind::FuzzerNoLink;
494
495
      // Enable coverage if the fuzzing flag is set.
496
0
      if (Add & SanitizerKind::FuzzerNoLink) {
497
0
        CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall |
498
0
                            CoverageTraceCmp | CoveragePCTable;
499
        // Due to TLS differences, stack depth tracking is only enabled on Linux
500
0
        if (TC.getTriple().isOSLinux())
501
0
          CoverageFeatures |= CoverageStackDepth;
502
0
      }
503
504
0
      Kinds |= Add;
505
0
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
506
0
      Arg->claim();
507
0
      SanitizerMask Remove = parseArgValues(D, Arg, DiagnoseErrors);
508
0
      AllRemove |= expandSanitizerGroups(Remove);
509
0
    }
510
0
  }
511
512
0
  std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
513
0
      std::make_pair(SanitizerKind::Address,
514
0
                     SanitizerKind::Thread | SanitizerKind::Memory),
515
0
      std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
516
0
      std::make_pair(SanitizerKind::Leak,
517
0
                     SanitizerKind::Thread | SanitizerKind::Memory),
518
0
      std::make_pair(SanitizerKind::KernelAddress,
519
0
                     SanitizerKind::Address | SanitizerKind::Leak |
520
0
                         SanitizerKind::Thread | SanitizerKind::Memory),
521
0
      std::make_pair(SanitizerKind::HWAddress,
522
0
                     SanitizerKind::Address | SanitizerKind::Thread |
523
0
                         SanitizerKind::Memory | SanitizerKind::KernelAddress),
524
0
      std::make_pair(SanitizerKind::Scudo,
525
0
                     SanitizerKind::Address | SanitizerKind::HWAddress |
526
0
                         SanitizerKind::Leak | SanitizerKind::Thread |
527
0
                         SanitizerKind::Memory | SanitizerKind::KernelAddress),
528
0
      std::make_pair(SanitizerKind::SafeStack,
529
0
                     (TC.getTriple().isOSFuchsia() ? SanitizerMask()
530
0
                                                   : SanitizerKind::Leak) |
531
0
                         SanitizerKind::Address | SanitizerKind::HWAddress |
532
0
                         SanitizerKind::Thread | SanitizerKind::Memory |
533
0
                         SanitizerKind::KernelAddress),
534
0
      std::make_pair(SanitizerKind::KernelHWAddress,
535
0
                     SanitizerKind::Address | SanitizerKind::HWAddress |
536
0
                         SanitizerKind::Leak | SanitizerKind::Thread |
537
0
                         SanitizerKind::Memory | SanitizerKind::KernelAddress |
538
0
                         SanitizerKind::SafeStack),
539
0
      std::make_pair(SanitizerKind::KernelMemory,
540
0
                     SanitizerKind::Address | SanitizerKind::HWAddress |
541
0
                         SanitizerKind::Leak | SanitizerKind::Thread |
542
0
                         SanitizerKind::Memory | SanitizerKind::KernelAddress |
543
0
                         SanitizerKind::Scudo | SanitizerKind::SafeStack),
544
0
      std::make_pair(SanitizerKind::MemTag,
545
0
                     SanitizerKind::Address | SanitizerKind::KernelAddress |
546
0
                         SanitizerKind::HWAddress |
547
0
                         SanitizerKind::KernelHWAddress),
548
0
      std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function)};
549
  // Enable toolchain specific default sanitizers if not explicitly disabled.
550
0
  SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
551
552
  // Disable default sanitizers that are incompatible with explicitly requested
553
  // ones.
554
0
  for (auto G : IncompatibleGroups) {
555
0
    SanitizerMask Group = G.first;
556
0
    if ((Default & Group) && (Kinds & G.second))
557
0
      Default &= ~Group;
558
0
  }
559
560
0
  Kinds |= Default;
561
562
  // We disable the vptr sanitizer if it was enabled by group expansion but RTTI
563
  // is disabled.
564
0
  if ((Kinds & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
565
0
    Kinds &= ~SanitizerKind::Vptr;
566
0
  }
567
568
  // Check that LTO is enabled if we need it.
569
0
  if ((Kinds & NeedsLTO) && !D.isUsingLTO() && DiagnoseErrors) {
570
0
    D.Diag(diag::err_drv_argument_only_allowed_with)
571
0
        << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
572
0
  }
573
574
0
  if ((Kinds & SanitizerKind::ShadowCallStack) && TC.getTriple().isAArch64() &&
575
0
      !llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) &&
576
0
      !Args.hasArg(options::OPT_ffixed_x18) && DiagnoseErrors) {
577
0
    D.Diag(diag::err_drv_argument_only_allowed_with)
578
0
        << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack)
579
0
        << "-ffixed-x18";
580
0
  }
581
582
  // Report error if there are non-trapping sanitizers that require
583
  // c++abi-specific  parts of UBSan runtime, and they are not provided by the
584
  // toolchain. We don't have a good way to check the latter, so we just
585
  // check if the toolchan supports vptr.
586
0
  if (~Supported & SanitizerKind::Vptr) {
587
0
    SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
588
    // The runtime library supports the Microsoft C++ ABI, but only well enough
589
    // for CFI. FIXME: Remove this once we support vptr on Windows.
590
0
    if (TC.getTriple().isOSWindows())
591
0
      KindsToDiagnose &= ~SanitizerKind::CFI;
592
0
    if (KindsToDiagnose) {
593
0
      SanitizerSet S;
594
0
      S.Mask = KindsToDiagnose;
595
0
      if (DiagnoseErrors)
596
0
        D.Diag(diag::err_drv_unsupported_opt_for_target)
597
0
            << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str();
598
0
      Kinds &= ~KindsToDiagnose;
599
0
    }
600
0
  }
601
602
  // Warn about incompatible groups of sanitizers.
603
0
  for (auto G : IncompatibleGroups) {
604
0
    SanitizerMask Group = G.first;
605
0
    if (Kinds & Group) {
606
0
      if (SanitizerMask Incompatible = Kinds & G.second) {
607
0
        if (DiagnoseErrors)
608
0
          D.Diag(clang::diag::err_drv_argument_not_allowed_with)
609
0
              << lastArgumentForMask(D, Args, Group)
610
0
              << lastArgumentForMask(D, Args, Incompatible);
611
0
        Kinds &= ~Incompatible;
612
0
      }
613
0
    }
614
0
  }
615
  // FIXME: Currently -fsanitize=leak is silently ignored in the presence of
616
  // -fsanitize=address. Perhaps it should print an error, or perhaps
617
  // -f(-no)sanitize=leak should change whether leak detection is enabled by
618
  // default in ASan?
619
620
  // Parse -f(no-)?sanitize-recover flags.
621
0
  SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable;
622
0
  SanitizerMask DiagnosedUnrecoverableKinds;
623
0
  SanitizerMask DiagnosedAlwaysRecoverableKinds;
624
0
  for (const auto *Arg : Args) {
625
0
    if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
626
0
      SanitizerMask Add = parseArgValues(D, Arg, DiagnoseErrors);
627
      // Report error if user explicitly tries to recover from unrecoverable
628
      // sanitizer.
629
0
      if (SanitizerMask KindsToDiagnose =
630
0
              Add & Unrecoverable & ~DiagnosedUnrecoverableKinds) {
631
0
        SanitizerSet SetToDiagnose;
632
0
        SetToDiagnose.Mask |= KindsToDiagnose;
633
0
        if (DiagnoseErrors)
634
0
          D.Diag(diag::err_drv_unsupported_option_argument)
635
0
              << Arg->getSpelling() << toString(SetToDiagnose);
636
0
        DiagnosedUnrecoverableKinds |= KindsToDiagnose;
637
0
      }
638
0
      RecoverableKinds |= expandSanitizerGroups(Add);
639
0
      Arg->claim();
640
0
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
641
0
      SanitizerMask Remove = parseArgValues(D, Arg, DiagnoseErrors);
642
      // Report error if user explicitly tries to disable recovery from
643
      // always recoverable sanitizer.
644
0
      if (SanitizerMask KindsToDiagnose =
645
0
              Remove & AlwaysRecoverable & ~DiagnosedAlwaysRecoverableKinds) {
646
0
        SanitizerSet SetToDiagnose;
647
0
        SetToDiagnose.Mask |= KindsToDiagnose;
648
0
        if (DiagnoseErrors)
649
0
          D.Diag(diag::err_drv_unsupported_option_argument)
650
0
              << Arg->getSpelling() << toString(SetToDiagnose);
651
0
        DiagnosedAlwaysRecoverableKinds |= KindsToDiagnose;
652
0
      }
653
0
      RecoverableKinds &= ~expandSanitizerGroups(Remove);
654
0
      Arg->claim();
655
0
    }
656
0
  }
657
0
  RecoverableKinds &= Kinds;
658
0
  RecoverableKinds &= ~Unrecoverable;
659
660
0
  TrappingKinds &= Kinds;
661
0
  RecoverableKinds &= ~TrappingKinds;
662
663
  // Setup ignorelist files.
664
  // Add default ignorelist from resource directory for activated sanitizers,
665
  // and validate special case lists format.
666
0
  if (!Args.hasArgNoClaim(options::OPT_fno_sanitize_ignorelist))
667
0
    addDefaultIgnorelists(D, Kinds, SystemIgnorelistFiles, DiagnoseErrors);
668
669
  // Parse -f(no-)?sanitize-ignorelist options.
670
  // This also validates special case lists format.
671
0
  parseSpecialCaseListArg(
672
0
      D, Args, UserIgnorelistFiles, options::OPT_fsanitize_ignorelist_EQ,
673
0
      options::OPT_fno_sanitize_ignorelist,
674
0
      clang::diag::err_drv_malformed_sanitizer_ignorelist, DiagnoseErrors);
675
676
  // Parse -f[no-]sanitize-memory-track-origins[=level] options.
677
0
  if (AllAddedKinds & SanitizerKind::Memory) {
678
0
    if (Arg *A =
679
0
            Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
680
0
                            options::OPT_fno_sanitize_memory_track_origins)) {
681
0
      if (!A->getOption().matches(
682
0
              options::OPT_fno_sanitize_memory_track_origins)) {
683
0
        StringRef S = A->getValue();
684
0
        if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
685
0
            MsanTrackOrigins > 2) {
686
0
          if (DiagnoseErrors)
687
0
            D.Diag(clang::diag::err_drv_invalid_value)
688
0
                << A->getAsString(Args) << S;
689
0
        }
690
0
      }
691
0
    }
692
0
    MsanUseAfterDtor = Args.hasFlag(
693
0
        options::OPT_fsanitize_memory_use_after_dtor,
694
0
        options::OPT_fno_sanitize_memory_use_after_dtor, MsanUseAfterDtor);
695
0
    MsanParamRetval = Args.hasFlag(
696
0
        options::OPT_fsanitize_memory_param_retval,
697
0
        options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
698
0
  } else if (AllAddedKinds & SanitizerKind::KernelMemory) {
699
0
    MsanUseAfterDtor = false;
700
0
    MsanParamRetval = Args.hasFlag(
701
0
        options::OPT_fsanitize_memory_param_retval,
702
0
        options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
703
0
  } else {
704
0
    MsanUseAfterDtor = false;
705
0
    MsanParamRetval = false;
706
0
  }
707
708
0
  if (AllAddedKinds & SanitizerKind::MemTag) {
709
0
    StringRef S =
710
0
        Args.getLastArgValue(options::OPT_fsanitize_memtag_mode_EQ, "sync");
711
0
    if (S == "async" || S == "sync") {
712
0
      MemtagMode = S.str();
713
0
    } else {
714
0
      D.Diag(clang::diag::err_drv_invalid_value_with_suggestion)
715
0
          << "-fsanitize-memtag-mode=" << S << "{async, sync}";
716
0
      MemtagMode = "sync";
717
0
    }
718
0
  }
719
720
0
  if (AllAddedKinds & SanitizerKind::Thread) {
721
0
    TsanMemoryAccess = Args.hasFlag(
722
0
        options::OPT_fsanitize_thread_memory_access,
723
0
        options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
724
0
    TsanFuncEntryExit = Args.hasFlag(
725
0
        options::OPT_fsanitize_thread_func_entry_exit,
726
0
        options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
727
0
    TsanAtomics =
728
0
        Args.hasFlag(options::OPT_fsanitize_thread_atomics,
729
0
                     options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
730
0
  }
731
732
0
  if (AllAddedKinds & SanitizerKind::CFI) {
733
    // Without PIE, external function address may resolve to a PLT record, which
734
    // can not be verified by the target module.
735
0
    NeedPIE |= CfiCrossDso;
736
0
    CfiICallGeneralizePointers =
737
0
        Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
738
739
0
    CfiICallNormalizeIntegers =
740
0
        Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
741
742
0
    if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors)
743
0
      D.Diag(diag::err_drv_argument_not_allowed_with)
744
0
          << "-fsanitize-cfi-cross-dso"
745
0
          << "-fsanitize-cfi-icall-generalize-pointers";
746
747
0
    CfiCanonicalJumpTables =
748
0
        Args.hasFlag(options::OPT_fsanitize_cfi_canonical_jump_tables,
749
0
                     options::OPT_fno_sanitize_cfi_canonical_jump_tables, true);
750
0
  }
751
752
0
  if (AllAddedKinds & SanitizerKind::KCFI) {
753
0
    CfiICallNormalizeIntegers =
754
0
        Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
755
756
0
    if (AllAddedKinds & SanitizerKind::CFI && DiagnoseErrors)
757
0
      D.Diag(diag::err_drv_argument_not_allowed_with)
758
0
          << "-fsanitize=kcfi"
759
0
          << lastArgumentForMask(D, Args, SanitizerKind::CFI);
760
0
  }
761
762
0
  Stats = Args.hasFlag(options::OPT_fsanitize_stats,
763
0
                       options::OPT_fno_sanitize_stats, false);
764
765
0
  if (MinimalRuntime) {
766
0
    SanitizerMask IncompatibleMask =
767
0
        Kinds & ~setGroupBits(CompatibleWithMinimalRuntime);
768
0
    if (IncompatibleMask && DiagnoseErrors)
769
0
      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
770
0
          << "-fsanitize-minimal-runtime"
771
0
          << lastArgumentForMask(D, Args, IncompatibleMask);
772
773
0
    SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds;
774
0
    if (NonTrappingCfi && DiagnoseErrors)
775
0
      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
776
0
          << "fsanitize-minimal-runtime"
777
0
          << "fsanitize-trap=cfi";
778
0
  }
779
780
  // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
781
  // enabled sanitizers.
782
0
  for (const auto *Arg : Args) {
783
0
    if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
784
0
      int LegacySanitizeCoverage;
785
0
      if (Arg->getNumValues() == 1 &&
786
0
          !StringRef(Arg->getValue(0))
787
0
               .getAsInteger(0, LegacySanitizeCoverage)) {
788
0
        CoverageFeatures = 0;
789
0
        Arg->claim();
790
0
        if (LegacySanitizeCoverage != 0 && DiagnoseErrors) {
791
0
          D.Diag(diag::warn_drv_deprecated_arg)
792
0
              << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard";
793
0
        }
794
0
        continue;
795
0
      }
796
0
      CoverageFeatures |= parseCoverageFeatures(D, Arg, DiagnoseErrors);
797
798
      // Disable coverage and not claim the flags if there is at least one
799
      // non-supporting sanitizer.
800
0
      if (!(AllAddedKinds & ~AllRemove & ~setGroupBits(SupportsCoverage))) {
801
0
        Arg->claim();
802
0
      } else {
803
0
        CoverageFeatures = 0;
804
0
      }
805
0
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
806
0
      Arg->claim();
807
0
      CoverageFeatures &= ~parseCoverageFeatures(D, Arg, DiagnoseErrors);
808
0
    }
809
0
  }
810
  // Choose at most one coverage type: function, bb, or edge.
811
0
  if (DiagnoseErrors) {
812
0
    if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageBB))
813
0
      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
814
0
          << "-fsanitize-coverage=func"
815
0
          << "-fsanitize-coverage=bb";
816
0
    if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageEdge))
817
0
      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
818
0
          << "-fsanitize-coverage=func"
819
0
          << "-fsanitize-coverage=edge";
820
0
    if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
821
0
      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
822
0
          << "-fsanitize-coverage=bb"
823
0
          << "-fsanitize-coverage=edge";
824
    // Basic block tracing and 8-bit counters require some type of coverage
825
    // enabled.
826
0
    if (CoverageFeatures & CoverageTraceBB)
827
0
      D.Diag(clang::diag::warn_drv_deprecated_arg)
828
0
          << "-fsanitize-coverage=trace-bb"
829
0
          << "-fsanitize-coverage=trace-pc-guard";
830
0
    if (CoverageFeatures & Coverage8bitCounters)
831
0
      D.Diag(clang::diag::warn_drv_deprecated_arg)
832
0
          << "-fsanitize-coverage=8bit-counters"
833
0
          << "-fsanitize-coverage=trace-pc-guard";
834
0
  }
835
836
0
  int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
837
0
  int InstrumentationTypes = CoverageTracePC | CoverageTracePCGuard |
838
0
                             CoverageInline8bitCounters | CoverageTraceLoads |
839
0
                             CoverageTraceStores | CoverageInlineBoolFlag |
840
0
                             CoverageControlFlow;
841
0
  if ((CoverageFeatures & InsertionPointTypes) &&
842
0
      !(CoverageFeatures & InstrumentationTypes) && DiagnoseErrors) {
843
0
    D.Diag(clang::diag::warn_drv_deprecated_arg)
844
0
        << "-fsanitize-coverage=[func|bb|edge]"
845
0
        << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc],["
846
0
           "control-flow]";
847
0
  }
848
849
  // trace-pc w/o func/bb/edge implies edge.
850
0
  if (!(CoverageFeatures & InsertionPointTypes)) {
851
0
    if (CoverageFeatures &
852
0
        (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters |
853
0
         CoverageInlineBoolFlag | CoverageControlFlow))
854
0
      CoverageFeatures |= CoverageEdge;
855
856
0
    if (CoverageFeatures & CoverageStackDepth)
857
0
      CoverageFeatures |= CoverageFunc;
858
0
  }
859
860
  // Parse -fsanitize-coverage-(allow|ignore)list options if coverage enabled.
861
  // This also validates special case lists format.
862
  // Here, OptSpecifier() acts as a never-matching command-line argument.
863
  // So, there is no way to clear coverage lists but you can append to them.
864
0
  if (CoverageFeatures) {
865
0
    parseSpecialCaseListArg(
866
0
        D, Args, CoverageAllowlistFiles,
867
0
        options::OPT_fsanitize_coverage_allowlist, OptSpecifier(),
868
0
        clang::diag::err_drv_malformed_sanitizer_coverage_allowlist,
869
0
        DiagnoseErrors);
870
0
    parseSpecialCaseListArg(
871
0
        D, Args, CoverageIgnorelistFiles,
872
0
        options::OPT_fsanitize_coverage_ignorelist, OptSpecifier(),
873
0
        clang::diag::err_drv_malformed_sanitizer_coverage_ignorelist,
874
0
        DiagnoseErrors);
875
0
  }
876
877
  // Parse -f(no-)?sanitize-metadata.
878
0
  for (const auto *Arg :
879
0
       Args.filtered(options::OPT_fexperimental_sanitize_metadata_EQ,
880
0
                     options::OPT_fno_experimental_sanitize_metadata_EQ)) {
881
0
    if (Arg->getOption().matches(
882
0
            options::OPT_fexperimental_sanitize_metadata_EQ)) {
883
0
      Arg->claim();
884
0
      BinaryMetadataFeatures |=
885
0
          parseBinaryMetadataFeatures(D, Arg, DiagnoseErrors);
886
0
    } else {
887
0
      Arg->claim();
888
0
      BinaryMetadataFeatures &=
889
0
          ~parseBinaryMetadataFeatures(D, Arg, DiagnoseErrors);
890
0
    }
891
0
  }
892
893
  // Parse -fsanitize-metadata-ignorelist option if enabled.
894
0
  if (BinaryMetadataFeatures) {
895
0
    parseSpecialCaseListArg(
896
0
        D, Args, BinaryMetadataIgnorelistFiles,
897
0
        options::OPT_fexperimental_sanitize_metadata_ignorelist_EQ,
898
0
        OptSpecifier(), // Cannot clear ignore list, only append.
899
0
        clang::diag::err_drv_malformed_sanitizer_metadata_ignorelist,
900
0
        DiagnoseErrors);
901
0
  }
902
903
0
  SharedRuntime =
904
0
      Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
905
0
                   TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() ||
906
0
                       TC.getTriple().isOSDarwin());
907
908
0
  ImplicitCfiRuntime = TC.getTriple().isAndroid();
909
910
0
  if (AllAddedKinds & SanitizerKind::Address) {
911
0
    NeedPIE |= TC.getTriple().isOSFuchsia();
912
0
    if (Arg *A =
913
0
            Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
914
0
      StringRef S = A->getValue();
915
      // Legal values are 0 and 1, 2, but in future we may add more levels.
916
0
      if ((S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
917
0
           AsanFieldPadding > 2) &&
918
0
          DiagnoseErrors) {
919
0
        D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
920
0
      }
921
0
    }
922
923
0
    if (Arg *WindowsDebugRTArg =
924
0
            Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
925
0
                            options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
926
0
                            options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
927
0
      switch (WindowsDebugRTArg->getOption().getID()) {
928
0
      case options::OPT__SLASH_MTd:
929
0
      case options::OPT__SLASH_MDd:
930
0
      case options::OPT__SLASH_LDd:
931
0
        if (DiagnoseErrors) {
932
0
          D.Diag(clang::diag::err_drv_argument_not_allowed_with)
933
0
              << WindowsDebugRTArg->getAsString(Args)
934
0
              << lastArgumentForMask(D, Args, SanitizerKind::Address);
935
0
          D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
936
0
        }
937
0
      }
938
0
    }
939
940
0
    StableABI = Args.hasFlag(options::OPT_fsanitize_stable_abi,
941
0
                             options::OPT_fno_sanitize_stable_abi, false);
942
943
0
    AsanUseAfterScope = Args.hasFlag(
944
0
        options::OPT_fsanitize_address_use_after_scope,
945
0
        options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
946
947
0
    AsanPoisonCustomArrayCookie = Args.hasFlag(
948
0
        options::OPT_fsanitize_address_poison_custom_array_cookie,
949
0
        options::OPT_fno_sanitize_address_poison_custom_array_cookie,
950
0
        AsanPoisonCustomArrayCookie);
951
952
0
    AsanOutlineInstrumentation =
953
0
        Args.hasFlag(options::OPT_fsanitize_address_outline_instrumentation,
954
0
                     options::OPT_fno_sanitize_address_outline_instrumentation,
955
0
                     AsanOutlineInstrumentation);
956
957
0
    AsanGlobalsDeadStripping = Args.hasFlag(
958
0
        options::OPT_fsanitize_address_globals_dead_stripping,
959
0
        options::OPT_fno_sanitize_address_globals_dead_stripping, true);
960
961
    // Enable ODR indicators which allow better handling of mixed instrumented
962
    // and uninstrumented globals. Disable them for Windows where weak odr
963
    // indicators (.weak.__odr_asan_gen*) may cause multiple definition linker
964
    // errors in the absence of -lldmingw.
965
0
    AsanUseOdrIndicator =
966
0
        Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
967
0
                     options::OPT_fno_sanitize_address_use_odr_indicator,
968
0
                     !TC.getTriple().isOSWindows());
969
970
0
    if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
971
0
      AsanInvalidPointerCmp = true;
972
0
    }
973
974
0
    if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
975
0
      AsanInvalidPointerSub = true;
976
0
    }
977
978
0
    if (TC.getTriple().isOSDarwin() &&
979
0
        (Args.hasArg(options::OPT_mkernel) ||
980
0
         Args.hasArg(options::OPT_fapple_kext))) {
981
0
      AsanDtorKind = llvm::AsanDtorKind::None;
982
0
    }
983
984
0
    if (const auto *Arg =
985
0
            Args.getLastArg(options::OPT_sanitize_address_destructor_EQ)) {
986
0
      auto parsedAsanDtorKind = AsanDtorKindFromString(Arg->getValue());
987
0
      if (parsedAsanDtorKind == llvm::AsanDtorKind::Invalid && DiagnoseErrors) {
988
0
        TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument)
989
0
            << Arg->getSpelling() << Arg->getValue();
990
0
      }
991
0
      AsanDtorKind = parsedAsanDtorKind;
992
0
    }
993
994
0
    if (const auto *Arg = Args.getLastArg(
995
0
            options::OPT_sanitize_address_use_after_return_EQ)) {
996
0
      auto parsedAsanUseAfterReturn =
997
0
          AsanDetectStackUseAfterReturnModeFromString(Arg->getValue());
998
0
      if (parsedAsanUseAfterReturn ==
999
0
              llvm::AsanDetectStackUseAfterReturnMode::Invalid &&
1000
0
          DiagnoseErrors) {
1001
0
        TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument)
1002
0
            << Arg->getSpelling() << Arg->getValue();
1003
0
      }
1004
0
      AsanUseAfterReturn = parsedAsanUseAfterReturn;
1005
0
    }
1006
1007
0
  } else {
1008
0
    AsanUseAfterScope = false;
1009
    // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address.
1010
0
    SanitizerMask DetectInvalidPointerPairs =
1011
0
        SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
1012
0
    if ((AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) &&
1013
0
        DiagnoseErrors) {
1014
0
      TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
1015
0
          << lastArgumentForMask(D, Args,
1016
0
                                 SanitizerKind::PointerCompare |
1017
0
                                     SanitizerKind::PointerSubtract)
1018
0
          << "-fsanitize=address";
1019
0
    }
1020
0
  }
1021
1022
0
  if (AllAddedKinds & SanitizerKind::HWAddress) {
1023
0
    if (Arg *HwasanAbiArg =
1024
0
            Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
1025
0
      HwasanAbi = HwasanAbiArg->getValue();
1026
0
      if (HwasanAbi != "platform" && HwasanAbi != "interceptor" &&
1027
0
          DiagnoseErrors)
1028
0
        D.Diag(clang::diag::err_drv_invalid_value)
1029
0
            << HwasanAbiArg->getAsString(Args) << HwasanAbi;
1030
0
    } else {
1031
0
      HwasanAbi = "interceptor";
1032
0
    }
1033
0
    if (TC.getTriple().getArch() == llvm::Triple::x86_64)
1034
0
      HwasanUseAliases = Args.hasFlag(
1035
0
          options::OPT_fsanitize_hwaddress_experimental_aliasing,
1036
0
          options::OPT_fno_sanitize_hwaddress_experimental_aliasing,
1037
0
          HwasanUseAliases);
1038
0
  }
1039
1040
0
  if (AllAddedKinds & SanitizerKind::SafeStack) {
1041
    // SafeStack runtime is built into the system on Android and Fuchsia.
1042
0
    SafeStackRuntime =
1043
0
        !TC.getTriple().isAndroid() && !TC.getTriple().isOSFuchsia();
1044
0
  }
1045
1046
0
  LinkRuntimes =
1047
0
      Args.hasFlag(options::OPT_fsanitize_link_runtime,
1048
0
                   options::OPT_fno_sanitize_link_runtime, LinkRuntimes);
1049
1050
  // Parse -link-cxx-sanitizer flag.
1051
0
  LinkCXXRuntimes = Args.hasArg(options::OPT_fsanitize_link_cxx_runtime,
1052
0
                                options::OPT_fno_sanitize_link_cxx_runtime,
1053
0
                                LinkCXXRuntimes) ||
1054
0
                    D.CCCIsCXX();
1055
1056
0
  NeedsMemProfRt = Args.hasFlag(options::OPT_fmemory_profile,
1057
0
                                options::OPT_fmemory_profile_EQ,
1058
0
                                options::OPT_fno_memory_profile, false);
1059
1060
  // Finally, initialize the set of available and recoverable sanitizers.
1061
0
  Sanitizers.Mask |= Kinds;
1062
0
  RecoverableSanitizers.Mask |= RecoverableKinds;
1063
0
  TrapSanitizers.Mask |= TrappingKinds;
1064
0
  assert(!(RecoverableKinds & TrappingKinds) &&
1065
0
         "Overlap between recoverable and trapping sanitizers");
1066
0
}
1067
1068
0
static std::string toString(const clang::SanitizerSet &Sanitizers) {
1069
0
  std::string Res;
1070
0
#define SANITIZER(NAME, ID)                                                    \
1071
0
  if (Sanitizers.has(SanitizerKind::ID)) {                                     \
1072
0
    if (!Res.empty())                                                          \
1073
0
      Res += ",";                                                              \
1074
0
    Res += NAME;                                                               \
1075
0
  }
1076
0
#include "clang/Basic/Sanitizers.def"
1077
0
  return Res;
1078
0
}
1079
1080
static void addSpecialCaseListOpt(const llvm::opt::ArgList &Args,
1081
                                  llvm::opt::ArgStringList &CmdArgs,
1082
                                  const char *SCLOptFlag,
1083
0
                                  const std::vector<std::string> &SCLFiles) {
1084
0
  for (const auto &SCLPath : SCLFiles) {
1085
0
    SmallString<64> SCLOpt(SCLOptFlag);
1086
0
    SCLOpt += SCLPath;
1087
0
    CmdArgs.push_back(Args.MakeArgString(SCLOpt));
1088
0
  }
1089
0
}
1090
1091
static void addIncludeLinkerOption(const ToolChain &TC,
1092
                                   const llvm::opt::ArgList &Args,
1093
                                   llvm::opt::ArgStringList &CmdArgs,
1094
0
                                   StringRef SymbolName) {
1095
0
  SmallString<64> LinkerOptionFlag;
1096
0
  LinkerOptionFlag = "--linker-option=/include:";
1097
0
  if (TC.getTriple().getArch() == llvm::Triple::x86) {
1098
    // Win32 mangles C function names with a '_' prefix.
1099
0
    LinkerOptionFlag += '_';
1100
0
  }
1101
0
  LinkerOptionFlag += SymbolName;
1102
0
  CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
1103
0
}
1104
1105
0
static bool hasTargetFeatureMTE(const llvm::opt::ArgStringList &CmdArgs) {
1106
0
  for (auto Start = CmdArgs.begin(), End = CmdArgs.end(); Start != End;
1107
0
       ++Start) {
1108
0
    auto It = std::find(Start, End, StringRef("+mte"));
1109
0
    if (It == End)
1110
0
      break;
1111
0
    if (It > Start && *std::prev(It) == StringRef("-target-feature"))
1112
0
      return true;
1113
0
    Start = It;
1114
0
  }
1115
0
  return false;
1116
0
}
1117
1118
void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
1119
                            llvm::opt::ArgStringList &CmdArgs,
1120
0
                            types::ID InputType) const {
1121
  // NVPTX doesn't currently support sanitizers.  Bailing out here means
1122
  // that e.g. -fsanitize=address applies only to host code, which is what we
1123
  // want for now.
1124
0
  if (TC.getTriple().isNVPTX())
1125
0
    return;
1126
  // AMDGPU sanitizer support is experimental and controlled by -fgpu-sanitize.
1127
0
  bool GPUSanitize = false;
1128
0
  if (TC.getTriple().isAMDGPU()) {
1129
0
    if (!Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
1130
0
                      true))
1131
0
      return;
1132
0
    GPUSanitize = true;
1133
0
  }
1134
1135
  // Translate available CoverageFeatures to corresponding clang-cc1 flags.
1136
  // Do it even if Sanitizers.empty() since some forms of coverage don't require
1137
  // sanitizers.
1138
0
  std::pair<int, const char *> CoverageFlags[] = {
1139
0
      std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
1140
0
      std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
1141
0
      std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
1142
0
      std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
1143
0
      std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
1144
0
      std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
1145
0
      std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
1146
0
      std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
1147
0
      std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
1148
0
      std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
1149
0
      std::make_pair(CoverageTracePCGuard,
1150
0
                     "-fsanitize-coverage-trace-pc-guard"),
1151
0
      std::make_pair(CoverageInline8bitCounters,
1152
0
                     "-fsanitize-coverage-inline-8bit-counters"),
1153
0
      std::make_pair(CoverageInlineBoolFlag,
1154
0
                     "-fsanitize-coverage-inline-bool-flag"),
1155
0
      std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
1156
0
      std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
1157
0
      std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth"),
1158
0
      std::make_pair(CoverageTraceLoads, "-fsanitize-coverage-trace-loads"),
1159
0
      std::make_pair(CoverageTraceStores, "-fsanitize-coverage-trace-stores"),
1160
0
      std::make_pair(CoverageControlFlow, "-fsanitize-coverage-control-flow")};
1161
0
  for (auto F : CoverageFlags) {
1162
0
    if (CoverageFeatures & F.first)
1163
0
      CmdArgs.push_back(F.second);
1164
0
  }
1165
0
  addSpecialCaseListOpt(
1166
0
      Args, CmdArgs, "-fsanitize-coverage-allowlist=", CoverageAllowlistFiles);
1167
0
  addSpecialCaseListOpt(Args, CmdArgs, "-fsanitize-coverage-ignorelist=",
1168
0
                        CoverageIgnorelistFiles);
1169
1170
0
  if (!GPUSanitize) {
1171
    // Translate available BinaryMetadataFeatures to corresponding clang-cc1
1172
    // flags. Does not depend on any other sanitizers. Unsupported on GPUs.
1173
0
    const std::pair<int, std::string> BinaryMetadataFlags[] = {
1174
0
        std::make_pair(BinaryMetadataCovered, "covered"),
1175
0
        std::make_pair(BinaryMetadataAtomics, "atomics"),
1176
0
        std::make_pair(BinaryMetadataUAR, "uar")};
1177
0
    for (const auto &F : BinaryMetadataFlags) {
1178
0
      if (BinaryMetadataFeatures & F.first)
1179
0
        CmdArgs.push_back(
1180
0
            Args.MakeArgString("-fexperimental-sanitize-metadata=" + F.second));
1181
0
    }
1182
0
    addSpecialCaseListOpt(Args, CmdArgs,
1183
0
                          "-fexperimental-sanitize-metadata-ignorelist=",
1184
0
                          BinaryMetadataIgnorelistFiles);
1185
0
  }
1186
1187
0
  if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
1188
    // Instruct the code generator to embed linker directives in the object file
1189
    // that cause the required runtime libraries to be linked.
1190
0
    CmdArgs.push_back(
1191
0
        Args.MakeArgString("--dependent-lib=" +
1192
0
                           TC.getCompilerRTBasename(Args, "ubsan_standalone")));
1193
0
    if (types::isCXX(InputType))
1194
0
      CmdArgs.push_back(Args.MakeArgString(
1195
0
          "--dependent-lib=" +
1196
0
          TC.getCompilerRTBasename(Args, "ubsan_standalone_cxx")));
1197
0
  }
1198
0
  if (TC.getTriple().isOSWindows() && needsStatsRt()) {
1199
0
    CmdArgs.push_back(Args.MakeArgString(
1200
0
        "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats_client")));
1201
1202
    // The main executable must export the stats runtime.
1203
    // FIXME: Only exporting from the main executable (e.g. based on whether the
1204
    // translation unit defines main()) would save a little space, but having
1205
    // multiple copies of the runtime shouldn't hurt.
1206
0
    CmdArgs.push_back(Args.MakeArgString(
1207
0
        "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats")));
1208
0
    addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
1209
0
  }
1210
1211
0
  if (Sanitizers.empty())
1212
0
    return;
1213
0
  CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
1214
1215
0
  if (!RecoverableSanitizers.empty())
1216
0
    CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
1217
0
                                         toString(RecoverableSanitizers)));
1218
1219
0
  if (!TrapSanitizers.empty())
1220
0
    CmdArgs.push_back(
1221
0
        Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
1222
1223
0
  addSpecialCaseListOpt(Args, CmdArgs,
1224
0
                        "-fsanitize-ignorelist=", UserIgnorelistFiles);
1225
0
  addSpecialCaseListOpt(Args, CmdArgs,
1226
0
                        "-fsanitize-system-ignorelist=", SystemIgnorelistFiles);
1227
1228
0
  if (MsanTrackOrigins)
1229
0
    CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
1230
0
                                         Twine(MsanTrackOrigins)));
1231
1232
0
  if (MsanUseAfterDtor)
1233
0
    CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
1234
1235
0
  if (!MsanParamRetval)
1236
0
    CmdArgs.push_back("-fno-sanitize-memory-param-retval");
1237
1238
  // FIXME: Pass these parameters as function attributes, not as -llvm flags.
1239
0
  if (!TsanMemoryAccess) {
1240
0
    CmdArgs.push_back("-mllvm");
1241
0
    CmdArgs.push_back("-tsan-instrument-memory-accesses=0");
1242
0
    CmdArgs.push_back("-mllvm");
1243
0
    CmdArgs.push_back("-tsan-instrument-memintrinsics=0");
1244
0
  }
1245
0
  if (!TsanFuncEntryExit) {
1246
0
    CmdArgs.push_back("-mllvm");
1247
0
    CmdArgs.push_back("-tsan-instrument-func-entry-exit=0");
1248
0
  }
1249
0
  if (!TsanAtomics) {
1250
0
    CmdArgs.push_back("-mllvm");
1251
0
    CmdArgs.push_back("-tsan-instrument-atomics=0");
1252
0
  }
1253
1254
0
  if (HwasanUseAliases) {
1255
0
    CmdArgs.push_back("-mllvm");
1256
0
    CmdArgs.push_back("-hwasan-experimental-use-page-aliases=1");
1257
0
  }
1258
1259
0
  if (CfiCrossDso)
1260
0
    CmdArgs.push_back("-fsanitize-cfi-cross-dso");
1261
1262
0
  if (CfiICallGeneralizePointers)
1263
0
    CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers");
1264
1265
0
  if (CfiICallNormalizeIntegers)
1266
0
    CmdArgs.push_back("-fsanitize-cfi-icall-experimental-normalize-integers");
1267
1268
0
  if (CfiCanonicalJumpTables)
1269
0
    CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables");
1270
1271
0
  if (Stats)
1272
0
    CmdArgs.push_back("-fsanitize-stats");
1273
1274
0
  if (MinimalRuntime)
1275
0
    CmdArgs.push_back("-fsanitize-minimal-runtime");
1276
1277
0
  if (AsanFieldPadding)
1278
0
    CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
1279
0
                                         Twine(AsanFieldPadding)));
1280
1281
0
  if (AsanUseAfterScope)
1282
0
    CmdArgs.push_back("-fsanitize-address-use-after-scope");
1283
1284
0
  if (AsanPoisonCustomArrayCookie)
1285
0
    CmdArgs.push_back("-fsanitize-address-poison-custom-array-cookie");
1286
1287
0
  if (AsanGlobalsDeadStripping)
1288
0
    CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
1289
1290
0
  if (!AsanUseOdrIndicator)
1291
0
    CmdArgs.push_back("-fno-sanitize-address-use-odr-indicator");
1292
1293
0
  if (AsanInvalidPointerCmp) {
1294
0
    CmdArgs.push_back("-mllvm");
1295
0
    CmdArgs.push_back("-asan-detect-invalid-pointer-cmp");
1296
0
  }
1297
1298
0
  if (AsanInvalidPointerSub) {
1299
0
    CmdArgs.push_back("-mllvm");
1300
0
    CmdArgs.push_back("-asan-detect-invalid-pointer-sub");
1301
0
  }
1302
1303
0
  if (AsanOutlineInstrumentation) {
1304
0
    CmdArgs.push_back("-mllvm");
1305
0
    CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
1306
0
  }
1307
1308
  // When emitting Stable ABI instrumentation, force outlining calls and avoid
1309
  // inlining shadow memory poisoning. While this is a big performance burden
1310
  // for now it allows full abstraction from implementation details.
1311
0
  if (StableABI) {
1312
0
    CmdArgs.push_back("-mllvm");
1313
0
    CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
1314
0
    CmdArgs.push_back("-mllvm");
1315
0
    CmdArgs.push_back("-asan-max-inline-poisoning-size=0");
1316
0
    CmdArgs.push_back("-mllvm");
1317
0
    CmdArgs.push_back("-asan-guard-against-version-mismatch=0");
1318
0
  }
1319
1320
  // Only pass the option to the frontend if the user requested,
1321
  // otherwise the frontend will just use the codegen default.
1322
0
  if (AsanDtorKind != llvm::AsanDtorKind::Invalid) {
1323
0
    CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-destructor=" +
1324
0
                                         AsanDtorKindToString(AsanDtorKind)));
1325
0
  }
1326
1327
0
  if (AsanUseAfterReturn != llvm::AsanDetectStackUseAfterReturnMode::Invalid) {
1328
0
    CmdArgs.push_back(Args.MakeArgString(
1329
0
        "-fsanitize-address-use-after-return=" +
1330
0
        AsanDetectStackUseAfterReturnModeToString(AsanUseAfterReturn)));
1331
0
  }
1332
1333
0
  if (!HwasanAbi.empty()) {
1334
0
    CmdArgs.push_back("-default-function-attr");
1335
0
    CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
1336
0
  }
1337
1338
0
  if (Sanitizers.has(SanitizerKind::HWAddress) && !HwasanUseAliases) {
1339
0
    CmdArgs.push_back("-target-feature");
1340
0
    CmdArgs.push_back("+tagged-globals");
1341
0
  }
1342
1343
  // MSan: Workaround for PR16386.
1344
  // ASan: This is mainly to help LSan with cases such as
1345
  // https://github.com/google/sanitizers/issues/373
1346
  // We can't make this conditional on -fsanitize=leak, as that flag shouldn't
1347
  // affect compilation.
1348
0
  if (Sanitizers.has(SanitizerKind::Memory) ||
1349
0
      Sanitizers.has(SanitizerKind::Address))
1350
0
    CmdArgs.push_back("-fno-assume-sane-operator-new");
1351
1352
  // libFuzzer wants to intercept calls to certain library functions, so the
1353
  // following -fno-builtin-* flags force the compiler to emit interposable
1354
  // libcalls to these functions. Other sanitizers effectively do the same thing
1355
  // by marking all library call sites with NoBuiltin attribute in their LLVM
1356
  // pass. (see llvm::maybeMarkSanitizerLibraryCallNoBuiltin)
1357
0
  if (Sanitizers.has(SanitizerKind::FuzzerNoLink)) {
1358
0
    CmdArgs.push_back("-fno-builtin-bcmp");
1359
0
    CmdArgs.push_back("-fno-builtin-memcmp");
1360
0
    CmdArgs.push_back("-fno-builtin-strncmp");
1361
0
    CmdArgs.push_back("-fno-builtin-strcmp");
1362
0
    CmdArgs.push_back("-fno-builtin-strncasecmp");
1363
0
    CmdArgs.push_back("-fno-builtin-strcasecmp");
1364
0
    CmdArgs.push_back("-fno-builtin-strstr");
1365
0
    CmdArgs.push_back("-fno-builtin-strcasestr");
1366
0
    CmdArgs.push_back("-fno-builtin-memmem");
1367
0
  }
1368
1369
  // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
1370
  // enabled.
1371
0
  if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
1372
0
      !Args.hasArg(options::OPT_fvisibility_EQ)) {
1373
0
    TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
1374
0
        << lastArgumentForMask(TC.getDriver(), Args,
1375
0
                               Sanitizers.Mask & CFIClasses)
1376
0
        << "-fvisibility=";
1377
0
  }
1378
1379
0
  if (Sanitizers.has(SanitizerKind::MemtagStack) &&
1380
0
      !hasTargetFeatureMTE(CmdArgs))
1381
0
    TC.getDriver().Diag(diag::err_stack_tagging_requires_hardware_feature);
1382
0
}
1383
1384
SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
1385
0
                             bool DiagnoseErrors) {
1386
0
  assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
1387
0
          A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1388
0
          A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1389
0
          A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1390
0
          A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1391
0
          A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
1392
0
         "Invalid argument in parseArgValues!");
1393
0
  SanitizerMask Kinds;
1394
0
  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1395
0
    const char *Value = A->getValue(i);
1396
0
    SanitizerMask Kind;
1397
    // Special case: don't accept -fsanitize=all.
1398
0
    if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
1399
0
        0 == strcmp("all", Value))
1400
0
      Kind = SanitizerMask();
1401
0
    else
1402
0
      Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
1403
1404
0
    if (Kind)
1405
0
      Kinds |= Kind;
1406
0
    else if (DiagnoseErrors)
1407
0
      D.Diag(clang::diag::err_drv_unsupported_option_argument)
1408
0
          << A->getSpelling() << Value;
1409
0
  }
1410
0
  return Kinds;
1411
0
}
1412
1413
int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A,
1414
0
                          bool DiagnoseErrors) {
1415
0
  assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
1416
0
         A->getOption().matches(options::OPT_fno_sanitize_coverage));
1417
0
  int Features = 0;
1418
0
  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1419
0
    const char *Value = A->getValue(i);
1420
0
    int F = llvm::StringSwitch<int>(Value)
1421
0
                .Case("func", CoverageFunc)
1422
0
                .Case("bb", CoverageBB)
1423
0
                .Case("edge", CoverageEdge)
1424
0
                .Case("indirect-calls", CoverageIndirCall)
1425
0
                .Case("trace-bb", CoverageTraceBB)
1426
0
                .Case("trace-cmp", CoverageTraceCmp)
1427
0
                .Case("trace-div", CoverageTraceDiv)
1428
0
                .Case("trace-gep", CoverageTraceGep)
1429
0
                .Case("8bit-counters", Coverage8bitCounters)
1430
0
                .Case("trace-pc", CoverageTracePC)
1431
0
                .Case("trace-pc-guard", CoverageTracePCGuard)
1432
0
                .Case("no-prune", CoverageNoPrune)
1433
0
                .Case("inline-8bit-counters", CoverageInline8bitCounters)
1434
0
                .Case("inline-bool-flag", CoverageInlineBoolFlag)
1435
0
                .Case("pc-table", CoveragePCTable)
1436
0
                .Case("stack-depth", CoverageStackDepth)
1437
0
                .Case("trace-loads", CoverageTraceLoads)
1438
0
                .Case("trace-stores", CoverageTraceStores)
1439
0
                .Case("control-flow", CoverageControlFlow)
1440
0
                .Default(0);
1441
0
    if (F == 0 && DiagnoseErrors)
1442
0
      D.Diag(clang::diag::err_drv_unsupported_option_argument)
1443
0
          << A->getSpelling() << Value;
1444
0
    Features |= F;
1445
0
  }
1446
0
  return Features;
1447
0
}
1448
1449
int parseBinaryMetadataFeatures(const Driver &D, const llvm::opt::Arg *A,
1450
0
                                bool DiagnoseErrors) {
1451
0
  assert(
1452
0
      A->getOption().matches(options::OPT_fexperimental_sanitize_metadata_EQ) ||
1453
0
      A->getOption().matches(
1454
0
          options::OPT_fno_experimental_sanitize_metadata_EQ));
1455
0
  int Features = 0;
1456
0
  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1457
0
    const char *Value = A->getValue(i);
1458
0
    int F = llvm::StringSwitch<int>(Value)
1459
0
                .Case("covered", BinaryMetadataCovered)
1460
0
                .Case("atomics", BinaryMetadataAtomics)
1461
0
                .Case("uar", BinaryMetadataUAR)
1462
0
                .Case("all", ~0)
1463
0
                .Default(0);
1464
0
    if (F == 0 && DiagnoseErrors)
1465
0
      D.Diag(clang::diag::err_drv_unsupported_option_argument)
1466
0
          << A->getSpelling() << Value;
1467
0
    Features |= F;
1468
0
  }
1469
0
  return Features;
1470
0
}
1471
1472
std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
1473
0
                                SanitizerMask Mask) {
1474
0
  for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
1475
0
                                                  E = Args.rend();
1476
0
       I != E; ++I) {
1477
0
    const auto *Arg = *I;
1478
0
    if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
1479
0
      SanitizerMask AddKinds =
1480
0
          expandSanitizerGroups(parseArgValues(D, Arg, false));
1481
0
      if (AddKinds & Mask)
1482
0
        return describeSanitizeArg(Arg, Mask);
1483
0
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1484
0
      SanitizerMask RemoveKinds =
1485
0
          expandSanitizerGroups(parseArgValues(D, Arg, false));
1486
0
      Mask &= ~RemoveKinds;
1487
0
    }
1488
0
  }
1489
0
  llvm_unreachable("arg list didn't provide expected value");
1490
0
}
1491
1492
0
std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
1493
0
  assert(A->getOption().matches(options::OPT_fsanitize_EQ) &&
1494
0
         "Invalid argument in describeSanitizerArg!");
1495
1496
0
  std::string Sanitizers;
1497
0
  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1498
0
    if (expandSanitizerGroups(
1499
0
            parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
1500
0
        Mask) {
1501
0
      if (!Sanitizers.empty())
1502
0
        Sanitizers += ",";
1503
0
      Sanitizers += A->getValue(i);
1504
0
    }
1505
0
  }
1506
1507
0
  assert(!Sanitizers.empty() && "arg didn't provide expected value");
1508
0
  return "-fsanitize=" + Sanitizers;
1509
0
}