Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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/StringSwitch.h"
17
#include "llvm/Support/FileSystem.h"
18
#include "llvm/Support/Path.h"
19
#include "llvm/Support/SpecialCaseList.h"
20
#include "llvm/Support/TargetParser.h"
21
#include <memory>
22
23
using namespace clang;
24
using namespace clang::driver;
25
using namespace llvm::opt;
26
27
static const SanitizerMask NeedsUbsanRt =
28
    SanitizerKind::Undefined | SanitizerKind::Integer |
29
    SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
30
    SanitizerKind::CFI | SanitizerKind::FloatDivideByZero;
31
static const SanitizerMask NeedsUbsanCxxRt =
32
    SanitizerKind::Vptr | SanitizerKind::CFI;
33
static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
34
static const SanitizerMask NotAllowedWithMinimalRuntime =
35
    SanitizerKind::Function | SanitizerKind::Vptr;
36
static const SanitizerMask RequiresPIE =
37
    SanitizerKind::DataFlow | SanitizerKind::HWAddress | SanitizerKind::Scudo;
38
static const SanitizerMask NeedsUnwindTables =
39
    SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread |
40
    SanitizerKind::Memory | SanitizerKind::DataFlow;
41
static const SanitizerMask SupportsCoverage =
42
    SanitizerKind::Address | SanitizerKind::HWAddress |
43
    SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
44
    SanitizerKind::MemTag | SanitizerKind::Memory |
45
    SanitizerKind::KernelMemory | SanitizerKind::Leak |
46
    SanitizerKind::Undefined | SanitizerKind::Integer |
47
    SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
48
    SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
49
    SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero;
50
static const SanitizerMask RecoverableByDefault =
51
    SanitizerKind::Undefined | SanitizerKind::Integer |
52
    SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
53
    SanitizerKind::FloatDivideByZero;
54
static const SanitizerMask Unrecoverable =
55
    SanitizerKind::Unreachable | SanitizerKind::Return;
56
static const SanitizerMask AlwaysRecoverable =
57
    SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress;
58
static const SanitizerMask LegacyFsanitizeRecoverMask =
59
    SanitizerKind::Undefined | SanitizerKind::Integer;
60
static const SanitizerMask NeedsLTO = SanitizerKind::CFI;
61
static const SanitizerMask TrappingSupported =
62
    (SanitizerKind::Undefined & ~SanitizerKind::Vptr) |
63
    SanitizerKind::UnsignedIntegerOverflow | SanitizerKind::ImplicitConversion |
64
    SanitizerKind::Nullability | SanitizerKind::LocalBounds |
65
    SanitizerKind::CFI | SanitizerKind::FloatDivideByZero;
66
static const SanitizerMask TrappingDefault = SanitizerKind::CFI;
67
static const SanitizerMask CFIClasses =
68
    SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
69
    SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
70
    SanitizerKind::CFIUnrelatedCast;
71
static const SanitizerMask CompatibleWithMinimalRuntime =
72
    TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack;
73
74
enum CoverageFeature {
75
  CoverageFunc = 1 << 0,
76
  CoverageBB = 1 << 1,
77
  CoverageEdge = 1 << 2,
78
  CoverageIndirCall = 1 << 3,
79
  CoverageTraceBB = 1 << 4,  // Deprecated.
80
  CoverageTraceCmp = 1 << 5,
81
  CoverageTraceDiv = 1 << 6,
82
  CoverageTraceGep = 1 << 7,
83
  Coverage8bitCounters = 1 << 8,  // Deprecated.
84
  CoverageTracePC = 1 << 9,
85
  CoverageTracePCGuard = 1 << 10,
86
  CoverageNoPrune = 1 << 11,
87
  CoverageInline8bitCounters = 1 << 12,
88
  CoveragePCTable = 1 << 13,
89
  CoverageStackDepth = 1 << 14,
90
};
91
92
/// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
93
/// invalid components. Returns a SanitizerMask.
94
static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
95
                                    bool DiagnoseErrors);
96
97
/// Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid
98
/// components. Returns OR of members of \c CoverageFeature enumeration.
99
static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A);
100
101
/// Produce an argument string from ArgList \p Args, which shows how it
102
/// provides some sanitizer kind from \p Mask. For example, the argument list
103
/// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
104
/// would produce "-fsanitize=vptr".
105
static std::string lastArgumentForMask(const Driver &D,
106
                                       const llvm::opt::ArgList &Args,
107
                                       SanitizerMask Mask);
108
109
/// Produce an argument string from argument \p A, which shows how it provides
110
/// a value in \p Mask. For instance, the argument
111
/// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
112
/// "-fsanitize=alignment".
113
static std::string describeSanitizeArg(const llvm::opt::Arg *A,
114
                                       SanitizerMask Mask);
115
116
/// Produce a string containing comma-separated names of sanitizers in \p
117
/// Sanitizers set.
118
static std::string toString(const clang::SanitizerSet &Sanitizers);
119
120
static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds,
121
31.0k
                                 std::vector<std::string> &BlacklistFiles) {
122
31.0k
  struct Blacklist {
123
31.0k
    const char *File;
124
31.0k
    SanitizerMask Mask;
125
31.0k
  } Blacklists[] = {{"asan_blacklist.txt", SanitizerKind::Address},
126
31.0k
                    {"hwasan_blacklist.txt", SanitizerKind::HWAddress},
127
31.0k
                    {"memtag_blacklist.txt", SanitizerKind::MemTag},
128
31.0k
                    {"msan_blacklist.txt", SanitizerKind::Memory},
129
31.0k
                    {"tsan_blacklist.txt", SanitizerKind::Thread},
130
31.0k
                    {"dfsan_abilist.txt", SanitizerKind::DataFlow},
131
31.0k
                    {"cfi_blacklist.txt", SanitizerKind::CFI},
132
31.0k
                    {"ubsan_blacklist.txt",
133
31.0k
                     SanitizerKind::Undefined | SanitizerKind::Integer |
134
31.0k
                         SanitizerKind::Nullability |
135
31.0k
                         SanitizerKind::FloatDivideByZero}};
136
31.0k
137
248k
  for (auto BL : Blacklists) {
138
248k
    if (!(Kinds & BL.Mask))
139
247k
      continue;
140
435
141
435
    clang::SmallString<64> Path(D.ResourceDir);
142
435
    llvm::sys::path::append(Path, "share", BL.File);
143
435
    if (llvm::sys::fs::exists(Path))
144
203
      BlacklistFiles.push_back(Path.str());
145
232
    else if (BL.Mask == SanitizerKind::CFI)
146
1
      // If cfi_blacklist.txt cannot be found in the resource dir, driver
147
1
      // should fail.
148
1
      D.Diag(clang::diag::err_drv_no_such_file) << Path;
149
435
  }
150
31.0k
}
151
152
/// Sets group bits for every group that has at least one representative already
153
/// enabled in \p Kinds.
154
62.0k
static SanitizerMask setGroupBits(SanitizerMask Kinds) {
155
62.0k
#define SANITIZER(NAME, ID)
156
62.0k
#define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
157
683k
  if (Kinds & SanitizerKind::ID)                                               \
158
683k
    
Kinds |= SanitizerKind::ID682k
##Group;
159
62.0k
#include "clang/Basic/Sanitizers.def"
160
62.0k
  return Kinds;
161
62.0k
}
162
163
static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
164
31.0k
                                           const llvm::opt::ArgList &Args) {
165
31.0k
  SanitizerMask TrapRemove;     // During the loop below, the accumulated set of
166
31.0k
                                // sanitizers disabled by the current sanitizer
167
31.0k
                                // argument or any argument after it.
168
31.0k
  SanitizerMask TrappingKinds;
169
31.0k
  SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported);
170
31.0k
171
31.0k
  for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
172
722k
       I != E; 
++I691k
) {
173
691k
    const auto *Arg = *I;
174
691k
    if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
175
10
      Arg->claim();
176
10
      SanitizerMask Add = parseArgValues(D, Arg, true);
177
10
      Add &= ~TrapRemove;
178
10
      if (SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) {
179
2
        SanitizerSet S;
180
2
        S.Mask = InvalidValues;
181
2
        D.Diag(diag::err_drv_unsupported_option_argument) << "-fsanitize-trap"
182
2
                                                          << toString(S);
183
2
      }
184
10
      TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove;
185
691k
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
186
8
      Arg->claim();
187
8
      TrapRemove |= expandSanitizerGroups(parseArgValues(D, Arg, true));
188
691k
    } else if (Arg->getOption().matches(
189
691k
                   options::OPT_fsanitize_undefined_trap_on_error)) {
190
7
      Arg->claim();
191
7
      TrappingKinds |=
192
7
          expandSanitizerGroups(SanitizerKind::UndefinedGroup & ~TrapRemove) &
193
7
          ~TrapRemove;
194
691k
    } else if (Arg->getOption().matches(
195
691k
                   options::OPT_fno_sanitize_undefined_trap_on_error)) {
196
0
      Arg->claim();
197
0
      TrapRemove |= expandSanitizerGroups(SanitizerKind::UndefinedGroup);
198
0
    }
199
691k
  }
200
31.0k
201
31.0k
  // Apply default trapping behavior.
202
31.0k
  TrappingKinds |= TrappingDefault & ~TrapRemove;
203
31.0k
204
31.0k
  return TrappingKinds;
205
31.0k
}
206
207
5.05k
bool SanitizerArgs::needsUbsanRt() const {
208
5.05k
  // All of these include ubsan.
209
5.05k
  if (needsAsanRt() || 
needsMsanRt()4.91k
||
needsHwasanRt()4.87k
||
needsTsanRt()4.85k
||
210
5.05k
      
needsDfsanRt()4.83k
||
needsLsanRt()4.82k
||
needsCfiDiagRt()4.79k
||
211
5.05k
      
(4.79k
needsScudoRt()4.79k
&&
!requiresMinimalRuntime()30
))
212
288
    return false;
213
4.77k
214
4.77k
  return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
215
4.77k
         
CoverageFeatures4.67k
;
216
4.77k
}
217
218
1.37k
bool SanitizerArgs::needsCfiRt() const {
219
1.37k
  return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
220
1.37k
         
CfiCrossDso1.37k
&&
!ImplicitCfiRuntime1
;
221
1.37k
}
222
223
6.17k
bool SanitizerArgs::needsCfiDiagRt() const {
224
6.17k
  return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
225
6.17k
         
CfiCrossDso8
&&
!ImplicitCfiRuntime3
;
226
6.17k
}
227
228
5.04k
bool SanitizerArgs::requiresPIE() const {
229
5.04k
  return NeedPIE || 
(Sanitizers.Mask & RequiresPIE)5.01k
;
230
5.04k
}
231
232
8.98k
bool SanitizerArgs::needsUnwindTables() const {
233
8.98k
  return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables);
234
8.98k
}
235
236
29.5k
bool SanitizerArgs::needsLTO() const {
237
29.5k
  return static_cast<bool>(Sanitizers.Mask & NeedsLTO);
238
29.5k
}
239
240
SanitizerArgs::SanitizerArgs(const ToolChain &TC,
241
31.0k
                             const llvm::opt::ArgList &Args) {
242
31.0k
  SanitizerMask AllRemove;      // During the loop below, the accumulated set of
243
31.0k
                                // sanitizers disabled by the current sanitizer
244
31.0k
                                // argument or any argument after it.
245
31.0k
  SanitizerMask AllAddedKinds;      // Mask of all sanitizers ever enabled by
246
31.0k
                                    // -fsanitize= flags (directly or via group
247
31.0k
                                    // expansion), some of which may be disabled
248
31.0k
                                    // later. Used to carefully prune
249
31.0k
                                    // unused-argument diagnostics.
250
31.0k
  SanitizerMask DiagnosedKinds;      // All Kinds we have diagnosed up to now.
251
31.0k
                                     // Used to deduplicate diagnostics.
252
31.0k
  SanitizerMask Kinds;
253
31.0k
  const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
254
31.0k
255
31.0k
  CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
256
31.0k
                             options::OPT_fno_sanitize_cfi_cross_dso, false);
257
31.0k
258
31.0k
  ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
259
31.0k
260
31.0k
  const Driver &D = TC.getDriver();
261
31.0k
  SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
262
31.0k
  SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
263
31.0k
264
31.0k
  MinimalRuntime =
265
31.0k
      Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
266
31.0k
                   options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
267
31.0k
268
31.0k
  // The object size sanitizer should not be enabled at -O0.
269
31.0k
  Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
270
31.0k
  bool RemoveObjectSizeAtO0 =
271
31.0k
      !OptLevel || 
OptLevel->getOption().matches(options::OPT_O0)14.4k
;
272
31.0k
273
31.0k
  for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
274
722k
       I != E; 
++I691k
) {
275
691k
    const auto *Arg = *I;
276
691k
    if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
277
609
      Arg->claim();
278
609
      SanitizerMask Add = parseArgValues(D, Arg, /*AllowGroups=*/true);
279
609
280
609
      if (RemoveObjectSizeAtO0) {
281
571
        AllRemove |= SanitizerKind::ObjectSize;
282
571
283
571
        // The user explicitly enabled the object size sanitizer. Warn
284
571
        // that this does nothing at -O0.
285
571
        if (Add & SanitizerKind::ObjectSize)
286
4
          D.Diag(diag::warn_drv_object_size_disabled_O0)
287
4
              << Arg->getAsString(Args);
288
571
      }
289
609
290
609
      AllAddedKinds |= expandSanitizerGroups(Add);
291
609
292
609
      // Avoid diagnosing any sanitizer which is disabled later.
293
609
      Add &= ~AllRemove;
294
609
      // At this point we have not expanded groups, so any unsupported
295
609
      // sanitizers in Add are those which have been explicitly enabled.
296
609
      // Diagnose them.
297
609
      if (SanitizerMask KindsToDiagnose =
298
2
              Add & InvalidTrappingKinds & ~DiagnosedKinds) {
299
2
        std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
300
2
        D.Diag(diag::err_drv_argument_not_allowed_with)
301
2
            << Desc << "-fsanitize-trap=undefined";
302
2
        DiagnosedKinds |= KindsToDiagnose;
303
2
      }
304
609
      Add &= ~InvalidTrappingKinds;
305
609
306
609
      if (MinimalRuntime) {
307
20
        if (SanitizerMask KindsToDiagnose =
308
2
                Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) {
309
2
          std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
310
2
          D.Diag(diag::err_drv_argument_not_allowed_with)
311
2
              << Desc << "-fsanitize-minimal-runtime";
312
2
          DiagnosedKinds |= KindsToDiagnose;
313
2
        }
314
20
        Add &= ~NotAllowedWithMinimalRuntime;
315
20
      }
316
609
317
609
      // FIXME: Make CFI on member function calls compatible with cross-DSO CFI.
318
609
      // There are currently two problems:
319
609
      // - Virtual function call checks need to pass a pointer to the function
320
609
      //   address to llvm.type.test and a pointer to the address point to the
321
609
      //   diagnostic function. Currently we pass the same pointer to both
322
609
      //   places.
323
609
      // - Non-virtual function call checks may need to check multiple type
324
609
      //   identifiers.
325
609
      // Fixing both of those may require changes to the cross-DSO CFI
326
609
      // interface.
327
609
      if (CfiCrossDso && 
(Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)9
) {
328
1
        D.Diag(diag::err_drv_argument_not_allowed_with)
329
1
            << "-fsanitize=cfi-mfcall"
330
1
            << "-fsanitize-cfi-cross-dso";
331
1
        Add &= ~SanitizerKind::CFIMFCall;
332
1
        DiagnosedKinds |= SanitizerKind::CFIMFCall;
333
1
      }
334
609
335
609
      if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
336
27
        std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
337
27
        D.Diag(diag::err_drv_unsupported_opt_for_target)
338
27
            << Desc << TC.getTriple().str();
339
27
        DiagnosedKinds |= KindsToDiagnose;
340
27
      }
341
609
      Add &= Supported;
342
609
343
609
      // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
344
609
      // so we don't error out if -fno-rtti and -fsanitize=undefined were
345
609
      // passed.
346
609
      if ((Add & SanitizerKind::Vptr) && 
(RTTIMode == ToolChain::RM_Disabled)11
) {
347
4
        if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) {
348
3
          assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
349
3
                  "RTTI disabled without -fno-rtti option?");
350
3
          // The user explicitly passed -fno-rtti with -fsanitize=vptr, but
351
3
          // the vptr sanitizer requires RTTI, so this is a user error.
352
3
          D.Diag(diag::err_drv_argument_not_allowed_with)
353
3
              << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
354
3
        } else {
355
1
          // The vptr sanitizer requires RTTI, but RTTI is disabled (by
356
1
          // default). Warn that the vptr sanitizer is being disabled.
357
1
          D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
358
1
        }
359
4
360
4
        // Take out the Vptr sanitizer from the enabled sanitizers
361
4
        AllRemove |= SanitizerKind::Vptr;
362
4
      }
363
609
364
609
      Add = expandSanitizerGroups(Add);
365
609
      // Group expansion may have enabled a sanitizer which is disabled later.
366
609
      Add &= ~AllRemove;
367
609
      // Silently discard any unsupported sanitizers implicitly enabled through
368
609
      // group expansion.
369
609
      Add &= ~InvalidTrappingKinds;
370
609
      if (MinimalRuntime) {
371
20
        Add &= ~NotAllowedWithMinimalRuntime;
372
20
      }
373
609
      if (CfiCrossDso)
374
9
        Add &= ~SanitizerKind::CFIMFCall;
375
609
      Add &= Supported;
376
609
377
609
      if (Add & SanitizerKind::Fuzzer)
378
7
        Add |= SanitizerKind::FuzzerNoLink;
379
609
380
609
      // Enable coverage if the fuzzing flag is set.
381
609
      if (Add & SanitizerKind::FuzzerNoLink) {
382
8
        CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall |
383
8
                            CoverageTraceCmp | CoveragePCTable;
384
8
        // Due to TLS differences, stack depth tracking is only enabled on Linux
385
8
        if (TC.getTriple().isOSLinux())
386
1
          CoverageFeatures |= CoverageStackDepth;
387
8
      }
388
609
389
609
      Kinds |= Add;
390
690k
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
391
1.79k
      Arg->claim();
392
1.79k
      SanitizerMask Remove = parseArgValues(D, Arg, true);
393
1.79k
      AllRemove |= expandSanitizerGroups(Remove);
394
1.79k
    }
395
691k
  }
396
31.0k
397
31.0k
  std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
398
31.0k
      std::make_pair(SanitizerKind::Address,
399
31.0k
                     SanitizerKind::Thread | SanitizerKind::Memory),
400
31.0k
      std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
401
31.0k
      std::make_pair(SanitizerKind::Leak,
402
31.0k
                     SanitizerKind::Thread | SanitizerKind::Memory),
403
31.0k
      std::make_pair(SanitizerKind::KernelAddress,
404
31.0k
                     SanitizerKind::Address | SanitizerKind::Leak |
405
31.0k
                         SanitizerKind::Thread | SanitizerKind::Memory),
406
31.0k
      std::make_pair(SanitizerKind::HWAddress,
407
31.0k
                     SanitizerKind::Address | SanitizerKind::Thread |
408
31.0k
                         SanitizerKind::Memory | SanitizerKind::KernelAddress),
409
31.0k
      std::make_pair(SanitizerKind::Scudo,
410
31.0k
                     SanitizerKind::Address | SanitizerKind::HWAddress |
411
31.0k
                         SanitizerKind::Leak | SanitizerKind::Thread |
412
31.0k
                         SanitizerKind::Memory | SanitizerKind::KernelAddress),
413
31.0k
      std::make_pair(SanitizerKind::SafeStack,
414
31.0k
                     SanitizerKind::Address | SanitizerKind::HWAddress |
415
31.0k
                         SanitizerKind::Leak | SanitizerKind::Thread |
416
31.0k
                         SanitizerKind::Memory | SanitizerKind::KernelAddress),
417
31.0k
      std::make_pair(SanitizerKind::KernelHWAddress,
418
31.0k
                     SanitizerKind::Address | SanitizerKind::HWAddress |
419
31.0k
                         SanitizerKind::Leak | SanitizerKind::Thread |
420
31.0k
                         SanitizerKind::Memory | SanitizerKind::KernelAddress |
421
31.0k
                         SanitizerKind::SafeStack),
422
31.0k
      std::make_pair(SanitizerKind::KernelMemory,
423
31.0k
                     SanitizerKind::Address | SanitizerKind::HWAddress |
424
31.0k
                         SanitizerKind::Leak | SanitizerKind::Thread |
425
31.0k
                         SanitizerKind::Memory | SanitizerKind::KernelAddress |
426
31.0k
                         SanitizerKind::Scudo | SanitizerKind::SafeStack),
427
31.0k
      std::make_pair(SanitizerKind::MemTag,
428
31.0k
                     SanitizerKind::Address | SanitizerKind::KernelAddress |
429
31.0k
                         SanitizerKind::HWAddress |
430
31.0k
                         SanitizerKind::KernelHWAddress)};
431
31.0k
  // Enable toolchain specific default sanitizers if not explicitly disabled.
432
31.0k
  SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
433
31.0k
434
31.0k
  // Disable default sanitizers that are incompatible with explicitly requested
435
31.0k
  // ones.
436
310k
  for (auto G : IncompatibleGroups) {
437
310k
    SanitizerMask Group = G.first;
438
310k
    if ((Default & Group) && 
(Kinds & G.second)44
)
439
5
      Default &= ~Group;
440
310k
  }
441
31.0k
442
31.0k
  Kinds |= Default;
443
31.0k
444
31.0k
  // We disable the vptr sanitizer if it was enabled by group expansion but RTTI
445
31.0k
  // is disabled.
446
31.0k
  if ((Kinds & SanitizerKind::Vptr) && 
(RTTIMode == ToolChain::RM_Disabled)58
) {
447
5
    Kinds &= ~SanitizerKind::Vptr;
448
5
  }
449
31.0k
450
31.0k
  // Check that LTO is enabled if we need it.
451
31.0k
  if ((Kinds & NeedsLTO) && 
!D.isUsingLTO()44
) {
452
14
    D.Diag(diag::err_drv_argument_only_allowed_with)
453
14
        << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
454
14
  }
455
31.0k
456
31.0k
  if ((Kinds & SanitizerKind::ShadowCallStack) &&
457
31.0k
      
TC.getTriple().getArch() == llvm::Triple::aarch648
&&
458
31.0k
      
!llvm::AArch64::isX18ReservedByDefault(TC.getTriple())4
&&
459
31.0k
      
!Args.hasArg(options::OPT_ffixed_x18)2
) {
460
1
    D.Diag(diag::err_drv_argument_only_allowed_with)
461
1
        << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack)
462
1
        << "-ffixed-x18";
463
1
  }
464
31.0k
465
31.0k
  // Report error if there are non-trapping sanitizers that require
466
31.0k
  // c++abi-specific  parts of UBSan runtime, and they are not provided by the
467
31.0k
  // toolchain. We don't have a good way to check the latter, so we just
468
31.0k
  // check if the toolchan supports vptr.
469
31.0k
  if (~Supported & SanitizerKind::Vptr) {
470
6.77k
    SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
471
6.77k
    // The runtime library supports the Microsoft C++ ABI, but only well enough
472
6.77k
    // for CFI. FIXME: Remove this once we support vptr on Windows.
473
6.77k
    if (TC.getTriple().isOSWindows())
474
773
      KindsToDiagnose &= ~SanitizerKind::CFI;
475
6.77k
    if (KindsToDiagnose) {
476
1
      SanitizerSet S;
477
1
      S.Mask = KindsToDiagnose;
478
1
      D.Diag(diag::err_drv_unsupported_opt_for_target)
479
1
          << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str();
480
1
      Kinds &= ~KindsToDiagnose;
481
1
    }
482
6.77k
  }
483
31.0k
484
31.0k
  // Warn about incompatible groups of sanitizers.
485
310k
  for (auto G : IncompatibleGroups) {
486
310k
    SanitizerMask Group = G.first;
487
310k
    if (Kinds & Group) {
488
397
      if (SanitizerMask Incompatible = Kinds & G.second) {
489
35
        D.Diag(clang::diag::err_drv_argument_not_allowed_with)
490
35
            << lastArgumentForMask(D, Args, Group)
491
35
            << lastArgumentForMask(D, Args, Incompatible);
492
35
        Kinds &= ~Incompatible;
493
35
      }
494
397
    }
495
310k
  }
496
31.0k
  // FIXME: Currently -fsanitize=leak is silently ignored in the presence of
497
31.0k
  // -fsanitize=address. Perhaps it should print an error, or perhaps
498
31.0k
  // -f(-no)sanitize=leak should change whether leak detection is enabled by
499
31.0k
  // default in ASan?
500
31.0k
501
31.0k
  // Parse -f(no-)?sanitize-recover flags.
502
31.0k
  SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable;
503
31.0k
  SanitizerMask DiagnosedUnrecoverableKinds;
504
31.0k
  SanitizerMask DiagnosedAlwaysRecoverableKinds;
505
691k
  for (const auto *Arg : Args) {
506
691k
    const char *DeprecatedReplacement = nullptr;
507
691k
    if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
508
2
      DeprecatedReplacement =
509
2
          "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all";
510
2
      RecoverableKinds |= expandSanitizerGroups(LegacyFsanitizeRecoverMask);
511
2
      Arg->claim();
512
691k
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
513
2
      DeprecatedReplacement = "-fno-sanitize-recover=undefined,integer' or "
514
2
                              "'-fno-sanitize-recover=all";
515
2
      RecoverableKinds &= ~expandSanitizerGroups(LegacyFsanitizeRecoverMask);
516
2
      Arg->claim();
517
691k
    } else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
518
13
      SanitizerMask Add = parseArgValues(D, Arg, true);
519
13
      // Report error if user explicitly tries to recover from unrecoverable
520
13
      // sanitizer.
521
13
      if (SanitizerMask KindsToDiagnose =
522
1
              Add & Unrecoverable & ~DiagnosedUnrecoverableKinds) {
523
1
        SanitizerSet SetToDiagnose;
524
1
        SetToDiagnose.Mask |= KindsToDiagnose;
525
1
        D.Diag(diag::err_drv_unsupported_option_argument)
526
1
            << Arg->getOption().getName() << toString(SetToDiagnose);
527
1
        DiagnosedUnrecoverableKinds |= KindsToDiagnose;
528
1
      }
529
13
      RecoverableKinds |= expandSanitizerGroups(Add);
530
13
      Arg->claim();
531
691k
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
532
10
      SanitizerMask Remove = parseArgValues(D, Arg, true);
533
10
      // Report error if user explicitly tries to disable recovery from
534
10
      // always recoverable sanitizer.
535
10
      if (SanitizerMask KindsToDiagnose =
536
2
              Remove & AlwaysRecoverable & ~DiagnosedAlwaysRecoverableKinds) {
537
2
        SanitizerSet SetToDiagnose;
538
2
        SetToDiagnose.Mask |= KindsToDiagnose;
539
2
        D.Diag(diag::err_drv_unsupported_option_argument)
540
2
            << Arg->getOption().getName() << toString(SetToDiagnose);
541
2
        DiagnosedAlwaysRecoverableKinds |= KindsToDiagnose;
542
2
      }
543
10
      RecoverableKinds &= ~expandSanitizerGroups(Remove);
544
10
      Arg->claim();
545
10
    }
546
691k
    if (DeprecatedReplacement) {
547
4
      D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
548
4
                                            << DeprecatedReplacement;
549
4
    }
550
691k
  }
551
31.0k
  RecoverableKinds &= Kinds;
552
31.0k
  RecoverableKinds &= ~Unrecoverable;
553
31.0k
554
31.0k
  TrappingKinds &= Kinds;
555
31.0k
  RecoverableKinds &= ~TrappingKinds;
556
31.0k
557
31.0k
  // Setup blacklist files.
558
31.0k
  // Add default blacklist from resource directory.
559
31.0k
  addDefaultBlacklists(D, Kinds, BlacklistFiles);
560
31.0k
  // Parse -f(no-)sanitize-blacklist options.
561
691k
  for (const auto *Arg : Args) {
562
691k
    if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) {
563
16
      Arg->claim();
564
16
      std::string BLPath = Arg->getValue();
565
16
      if (llvm::sys::fs::exists(BLPath)) {
566
15
        BlacklistFiles.push_back(BLPath);
567
15
        ExtraDeps.push_back(BLPath);
568
15
      } else {
569
1
        D.Diag(clang::diag::err_drv_no_such_file) << BLPath;
570
1
      }
571
691k
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
572
3
      Arg->claim();
573
3
      BlacklistFiles.clear();
574
3
      ExtraDeps.clear();
575
3
    }
576
691k
  }
577
31.0k
  // Validate blacklists format.
578
31.0k
  {
579
31.0k
    std::string BLError;
580
31.0k
    std::unique_ptr<llvm::SpecialCaseList> SCL(
581
31.0k
        llvm::SpecialCaseList::create(BlacklistFiles, BLError));
582
31.0k
    if (!SCL.get())
583
1
      D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
584
31.0k
  }
585
31.0k
586
31.0k
  // Parse -f[no-]sanitize-memory-track-origins[=level] options.
587
31.0k
  if (AllAddedKinds & SanitizerKind::Memory) {
588
61
    if (Arg *A =
589
16
            Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
590
16
                            options::OPT_fsanitize_memory_track_origins,
591
16
                            options::OPT_fno_sanitize_memory_track_origins)) {
592
16
      if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
593
6
        MsanTrackOrigins = 2;
594
10
      } else if (A->getOption().matches(
595
10
                     options::OPT_fno_sanitize_memory_track_origins)) {
596
3
        MsanTrackOrigins = 0;
597
7
      } else {
598
7
        StringRef S = A->getValue();
599
7
        if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
600
7
            MsanTrackOrigins > 2) {
601
1
          D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
602
1
        }
603
7
      }
604
16
    }
605
61
    MsanUseAfterDtor =
606
61
        Args.hasFlag(options::OPT_fsanitize_memory_use_after_dtor,
607
61
                     options::OPT_fno_sanitize_memory_use_after_dtor,
608
61
                     MsanUseAfterDtor);
609
61
    NeedPIE |= !(TC.getTriple().isOSLinux() &&
610
61
                 
TC.getTriple().getArch() == llvm::Triple::x86_6453
);
611
30.9k
  } else {
612
30.9k
    MsanUseAfterDtor = false;
613
30.9k
  }
614
31.0k
615
31.0k
  if (AllAddedKinds & SanitizerKind::Thread) {
616
50
    TsanMemoryAccess = Args.hasFlag(
617
50
        options::OPT_fsanitize_thread_memory_access,
618
50
        options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
619
50
    TsanFuncEntryExit = Args.hasFlag(
620
50
        options::OPT_fsanitize_thread_func_entry_exit,
621
50
        options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
622
50
    TsanAtomics =
623
50
        Args.hasFlag(options::OPT_fsanitize_thread_atomics,
624
50
                     options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
625
50
  }
626
31.0k
627
31.0k
  if (AllAddedKinds & SanitizerKind::CFI) {
628
46
    // Without PIE, external function address may resolve to a PLT record, which
629
46
    // can not be verified by the target module.
630
46
    NeedPIE |= CfiCrossDso;
631
46
    CfiICallGeneralizePointers =
632
46
        Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
633
46
634
46
    if (CfiCrossDso && 
CfiICallGeneralizePointers9
)
635
1
      D.Diag(diag::err_drv_argument_not_allowed_with)
636
1
          << "-fsanitize-cfi-cross-dso"
637
1
          << "-fsanitize-cfi-icall-generalize-pointers";
638
46
  }
639
31.0k
640
31.0k
  Stats = Args.hasFlag(options::OPT_fsanitize_stats,
641
31.0k
                       options::OPT_fno_sanitize_stats, false);
642
31.0k
643
31.0k
  if (MinimalRuntime) {
644
17
    SanitizerMask IncompatibleMask =
645
17
        Kinds & ~setGroupBits(CompatibleWithMinimalRuntime);
646
17
    if (IncompatibleMask)
647
4
      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
648
4
          << "-fsanitize-minimal-runtime"
649
4
          << lastArgumentForMask(D, Args, IncompatibleMask);
650
17
651
17
    SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds;
652
17
    if (NonTrappingCfi)
653
1
      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
654
1
          << "fsanitize-minimal-runtime"
655
1
          << "fsanitize-trap=cfi";
656
17
  }
657
31.0k
658
31.0k
  // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
659
31.0k
  // enabled sanitizers.
660
691k
  for (const auto *Arg : Args) {
661
691k
    if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
662
58
      int LegacySanitizeCoverage;
663
58
      if (Arg->getNumValues() == 1 &&
664
58
          !StringRef(Arg->getValue(0))
665
31
               .getAsInteger(0, LegacySanitizeCoverage)) {
666
3
        CoverageFeatures = 0;
667
3
        Arg->claim();
668
3
        if (LegacySanitizeCoverage != 0) {
669
1
          D.Diag(diag::warn_drv_deprecated_arg)
670
1
              << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard";
671
1
        }
672
3
        continue;
673
3
      }
674
55
      CoverageFeatures |= parseCoverageFeatures(D, Arg);
675
55
676
55
      // Disable coverage and not claim the flags if there is at least one
677
55
      // non-supporting sanitizer.
678
55
      if (!(AllAddedKinds & ~AllRemove & ~setGroupBits(SupportsCoverage))) {
679
54
        Arg->claim();
680
54
      } else {
681
1
        CoverageFeatures = 0;
682
1
      }
683
690k
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
684
1
      Arg->claim();
685
1
      CoverageFeatures &= ~parseCoverageFeatures(D, Arg);
686
1
    }
687
691k
  }
688
31.0k
  // Choose at most one coverage type: function, bb, or edge.
689
31.0k
  if ((CoverageFeatures & CoverageFunc) && 
(CoverageFeatures & CoverageBB)26
)
690
0
    D.Diag(clang::diag::err_drv_argument_not_allowed_with)
691
0
        << "-fsanitize-coverage=func"
692
0
        << "-fsanitize-coverage=bb";
693
31.0k
  if ((CoverageFeatures & CoverageFunc) && 
(CoverageFeatures & CoverageEdge)26
)
694
1
    D.Diag(clang::diag::err_drv_argument_not_allowed_with)
695
1
        << "-fsanitize-coverage=func"
696
1
        << "-fsanitize-coverage=edge";
697
31.0k
  if ((CoverageFeatures & CoverageBB) && 
(CoverageFeatures & CoverageEdge)5
)
698
0
    D.Diag(clang::diag::err_drv_argument_not_allowed_with)
699
0
        << "-fsanitize-coverage=bb"
700
0
        << "-fsanitize-coverage=edge";
701
31.0k
  // Basic block tracing and 8-bit counters require some type of coverage
702
31.0k
  // enabled.
703
31.0k
  if (CoverageFeatures & CoverageTraceBB)
704
1
    D.Diag(clang::diag::warn_drv_deprecated_arg)
705
1
        << "-fsanitize-coverage=trace-bb"
706
1
        << "-fsanitize-coverage=trace-pc-guard";
707
31.0k
  if (CoverageFeatures & Coverage8bitCounters)
708
1
    D.Diag(clang::diag::warn_drv_deprecated_arg)
709
1
        << "-fsanitize-coverage=8bit-counters"
710
1
        << "-fsanitize-coverage=trace-pc-guard";
711
31.0k
712
31.0k
  int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
713
31.0k
  int InstrumentationTypes =
714
31.0k
      CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters;
715
31.0k
  if ((CoverageFeatures & InsertionPointTypes) &&
716
31.0k
      
!(CoverageFeatures & InstrumentationTypes)37
) {
717
17
    D.Diag(clang::diag::warn_drv_deprecated_arg)
718
17
        << "-fsanitize-coverage=[func|bb|edge]"
719
17
        << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
720
17
  }
721
31.0k
722
31.0k
  // trace-pc w/o func/bb/edge implies edge.
723
31.0k
  if (!(CoverageFeatures & InsertionPointTypes)) {
724
30.9k
    if (CoverageFeatures &
725
30.9k
        (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters))
726
16
      CoverageFeatures |= CoverageEdge;
727
30.9k
728
30.9k
    if (CoverageFeatures & CoverageStackDepth)
729
3
      CoverageFeatures |= CoverageFunc;
730
30.9k
  }
731
31.0k
732
31.0k
  SharedRuntime =
733
31.0k
      Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
734
31.0k
                   TC.getTriple().isAndroid() || 
TC.getTriple().isOSFuchsia()30.8k
||
735
31.0k
                       
TC.getTriple().isOSDarwin()30.7k
);
736
31.0k
737
31.0k
  ImplicitCfiRuntime = TC.getTriple().isAndroid();
738
31.0k
739
31.0k
  if (AllAddedKinds & SanitizerKind::Address) {
740
173
    NeedPIE |= TC.getTriple().isOSFuchsia();
741
173
    if (Arg *A =
742
5
            Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
743
5
        StringRef S = A->getValue();
744
5
        // Legal values are 0 and 1, 2, but in future we may add more levels.
745
5
        if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
746
5
            AsanFieldPadding > 2) {
747
1
          D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
748
1
        }
749
5
    }
750
173
751
173
    if (Arg *WindowsDebugRTArg =
752
15
            Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
753
15
                            options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
754
15
                            options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
755
15
      switch (WindowsDebugRTArg->getOption().getID()) {
756
15
      case options::OPT__SLASH_MTd:
757
7
      case options::OPT__SLASH_MDd:
758
7
      case options::OPT__SLASH_LDd:
759
7
        D.Diag(clang::diag::err_drv_argument_not_allowed_with)
760
7
            << WindowsDebugRTArg->getAsString(Args)
761
7
            << lastArgumentForMask(D, Args, SanitizerKind::Address);
762
7
        D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
763
15
      }
764
15
    }
765
173
766
173
    AsanUseAfterScope = Args.hasFlag(
767
173
        options::OPT_fsanitize_address_use_after_scope,
768
173
        options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
769
173
770
173
    AsanPoisonCustomArrayCookie = Args.hasFlag(
771
173
        options::OPT_fsanitize_address_poison_custom_array_cookie,
772
173
        options::OPT_fno_sanitize_address_poison_custom_array_cookie,
773
173
        AsanPoisonCustomArrayCookie);
774
173
775
173
    // As a workaround for a bug in gold 2.26 and earlier, dead stripping of
776
173
    // globals in ASan is disabled by default on ELF targets.
777
173
    // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
778
173
    AsanGlobalsDeadStripping =
779
173
        !TC.getTriple().isOSBinFormatELF() || 
TC.getTriple().isOSFuchsia()128
||
780
173
        
TC.getTriple().isPS4()123
||
781
173
        
Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping)115
;
782
173
783
173
    AsanUseOdrIndicator =
784
173
        Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
785
173
                     options::OPT_fno_sanitize_address_use_odr_indicator,
786
173
                     AsanUseOdrIndicator);
787
173
788
173
    if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
789
1
      AsanInvalidPointerCmp = true;
790
1
    }
791
173
792
173
    if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
793
1
      AsanInvalidPointerSub = true;
794
1
    }
795
173
796
30.8k
  } else {
797
30.8k
    AsanUseAfterScope = false;
798
30.8k
    // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address.
799
30.8k
    SanitizerMask DetectInvalidPointerPairs =
800
30.8k
        SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
801
30.8k
    if (AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) {
802
2
      TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
803
2
          << lastArgumentForMask(D, Args,
804
2
                                 SanitizerKind::PointerCompare |
805
2
                                     SanitizerKind::PointerSubtract)
806
2
          << "-fsanitize=address";
807
2
    }
808
30.8k
  }
809
31.0k
810
31.0k
  if (AllAddedKinds & SanitizerKind::HWAddress) {
811
28
    if (Arg *HwasanAbiArg =
812
3
            Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
813
3
      HwasanAbi = HwasanAbiArg->getValue();
814
3
      if (HwasanAbi != "platform" && 
HwasanAbi != "interceptor"2
)
815
1
        D.Diag(clang::diag::err_drv_invalid_value)
816
1
            << HwasanAbiArg->getAsString(Args) << HwasanAbi;
817
25
    } else {
818
25
      HwasanAbi = "interceptor";
819
25
    }
820
28
  }
821
31.0k
822
31.0k
  if (AllAddedKinds & SanitizerKind::SafeStack) {
823
20
    // SafeStack runtime is built into the system on Fuchsia.
824
20
    SafeStackRuntime = !TC.getTriple().isOSFuchsia();
825
20
  }
826
31.0k
827
31.0k
  // Parse -link-cxx-sanitizer flag.
828
31.0k
  LinkCXXRuntimes =
829
31.0k
      Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || 
D.CCCIsCXX()31.0k
;
830
31.0k
831
31.0k
  // Finally, initialize the set of available and recoverable sanitizers.
832
31.0k
  Sanitizers.Mask |= Kinds;
833
31.0k
  RecoverableSanitizers.Mask |= RecoverableKinds;
834
31.0k
  TrapSanitizers.Mask |= TrappingKinds;
835
31.0k
  assert(!(RecoverableKinds & TrappingKinds) &&
836
31.0k
         "Overlap between recoverable and trapping sanitizers");
837
31.0k
}
838
839
771
static std::string toString(const clang::SanitizerSet &Sanitizers) {
840
771
  std::string Res;
841
771
#define SANITIZER(NAME, ID)                                                    \
842
40.8k
  if (Sanitizers.has(SanitizerKind::ID)) {                                     \
843
3.46k
    if (!Res.empty())                                                          \
844
3.46k
      
Res += ","2.69k
; \
845
3.46k
    Res += NAME;                                                               \
846
3.46k
  }
847
771
#include "clang/Basic/Sanitizers.def"
848
771
  return Res;
849
771
}
850
851
static void addIncludeLinkerOption(const ToolChain &TC,
852
                                   const llvm::opt::ArgList &Args,
853
                                   llvm::opt::ArgStringList &CmdArgs,
854
2
                                   StringRef SymbolName) {
855
2
  SmallString<64> LinkerOptionFlag;
856
2
  LinkerOptionFlag = "--linker-option=/include:";
857
2
  if (TC.getTriple().getArch() == llvm::Triple::x86) {
858
1
    // Win32 mangles C function names with a '_' prefix.
859
1
    LinkerOptionFlag += '_';
860
1
  }
861
2
  LinkerOptionFlag += SymbolName;
862
2
  CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
863
2
}
864
865
void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
866
                            llvm::opt::ArgStringList &CmdArgs,
867
29.5k
                            types::ID InputType) const {
868
29.5k
  // NVPTX doesn't currently support sanitizers.  Bailing out here means that
869
29.5k
  // e.g. -fsanitize=address applies only to host code, which is what we want
870
29.5k
  // for now.
871
29.5k
  if (TC.getTriple().isNVPTX())
872
308
    return;
873
29.2k
874
29.2k
  // Translate available CoverageFeatures to corresponding clang-cc1 flags.
875
29.2k
  // Do it even if Sanitizers.empty() since some forms of coverage don't require
876
29.2k
  // sanitizers.
877
29.2k
  std::pair<int, const char *> CoverageFlags[] = {
878
29.2k
    std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
879
29.2k
    std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
880
29.2k
    std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
881
29.2k
    std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
882
29.2k
    std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
883
29.2k
    std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
884
29.2k
    std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
885
29.2k
    std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
886
29.2k
    std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
887
29.2k
    std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
888
29.2k
    std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"),
889
29.2k
    std::make_pair(CoverageInline8bitCounters, "-fsanitize-coverage-inline-8bit-counters"),
890
29.2k
    std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
891
29.2k
    std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
892
29.2k
    std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth")};
893
439k
  for (auto F : CoverageFlags) {
894
439k
    if (CoverageFeatures & F.first)
895
136
      CmdArgs.push_back(F.second);
896
439k
  }
897
29.2k
898
29.2k
  if (TC.getTriple().isOSWindows() && 
needsUbsanRt()799
) {
899
8
    // Instruct the code generator to embed linker directives in the object file
900
8
    // that cause the required runtime libraries to be linked.
901
8
    CmdArgs.push_back(Args.MakeArgString(
902
8
        "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone")));
903
8
    if (types::isCXX(InputType))
904
2
      CmdArgs.push_back(Args.MakeArgString(
905
2
          "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx")));
906
8
  }
907
29.2k
  if (TC.getTriple().isOSWindows() && 
needsStatsRt()799
) {
908
2
    CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" +
909
2
                                         TC.getCompilerRT(Args, "stats_client")));
910
2
911
2
    // The main executable must export the stats runtime.
912
2
    // FIXME: Only exporting from the main executable (e.g. based on whether the
913
2
    // translation unit defines main()) would save a little space, but having
914
2
    // multiple copies of the runtime shouldn't hurt.
915
2
    CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" +
916
2
                                         TC.getCompilerRT(Args, "stats")));
917
2
    addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
918
2
  }
919
29.2k
920
29.2k
  if (Sanitizers.empty())
921
28.7k
    return;
922
585
  CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
923
585
924
585
  if (!RecoverableSanitizers.empty())
925
129
    CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
926
129
                                         toString(RecoverableSanitizers)));
927
585
928
585
  if (!TrapSanitizers.empty())
929
51
    CmdArgs.push_back(
930
51
        Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
931
585
932
585
  for (const auto &BLPath : BlacklistFiles) {
933
210
    SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
934
210
    BlacklistOpt += BLPath;
935
210
    CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
936
210
  }
937
585
  for (const auto &Dep : ExtraDeps) {
938
11
    SmallString<64> ExtraDepOpt("-fdepfile-entry=");
939
11
    ExtraDepOpt += Dep;
940
11
    CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
941
11
  }
942
585
943
585
  if (MsanTrackOrigins)
944
9
    CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
945
9
                                         Twine(MsanTrackOrigins)));
946
585
947
585
  if (MsanUseAfterDtor)
948
54
    CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
949
585
950
585
  // FIXME: Pass these parameters as function attributes, not as -llvm flags.
951
585
  if (!TsanMemoryAccess) {
952
2
    CmdArgs.push_back("-mllvm");
953
2
    CmdArgs.push_back("-tsan-instrument-memory-accesses=0");
954
2
    CmdArgs.push_back("-mllvm");
955
2
    CmdArgs.push_back("-tsan-instrument-memintrinsics=0");
956
2
  }
957
585
  if (!TsanFuncEntryExit) {
958
2
    CmdArgs.push_back("-mllvm");
959
2
    CmdArgs.push_back("-tsan-instrument-func-entry-exit=0");
960
2
  }
961
585
  if (!TsanAtomics) {
962
2
    CmdArgs.push_back("-mllvm");
963
2
    CmdArgs.push_back("-tsan-instrument-atomics=0");
964
2
  }
965
585
966
585
  if (CfiCrossDso)
967
8
    CmdArgs.push_back("-fsanitize-cfi-cross-dso");
968
585
969
585
  if (CfiICallGeneralizePointers)
970
2
    CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers");
971
585
972
585
  if (Stats)
973
5
    CmdArgs.push_back("-fsanitize-stats");
974
585
975
585
  if (MinimalRuntime)
976
17
    CmdArgs.push_back("-fsanitize-minimal-runtime");
977
585
978
585
  if (AsanFieldPadding)
979
3
    CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
980
3
                                         Twine(AsanFieldPadding)));
981
585
982
585
  if (AsanUseAfterScope)
983
167
    CmdArgs.push_back("-fsanitize-address-use-after-scope");
984
585
985
585
  if (AsanPoisonCustomArrayCookie)
986
4
    CmdArgs.push_back("-fsanitize-address-poison-custom-array-cookie");
987
585
988
585
  if (AsanGlobalsDeadStripping)
989
59
    CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
990
585
991
585
  if (AsanUseOdrIndicator)
992
4
    CmdArgs.push_back("-fsanitize-address-use-odr-indicator");
993
585
994
585
  if (AsanInvalidPointerCmp) {
995
1
    CmdArgs.push_back("-mllvm");
996
1
    CmdArgs.push_back("-asan-detect-invalid-pointer-cmp");
997
1
  }
998
585
999
585
  if (AsanInvalidPointerSub) {
1000
1
    CmdArgs.push_back("-mllvm");
1001
1
    CmdArgs.push_back("-asan-detect-invalid-pointer-sub");
1002
1
  }
1003
585
1004
585
  if (!HwasanAbi.empty()) {
1005
28
    CmdArgs.push_back("-default-function-attr");
1006
28
    CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
1007
28
  }
1008
585
1009
585
  // MSan: Workaround for PR16386.
1010
585
  // ASan: This is mainly to help LSan with cases such as
1011
585
  // https://github.com/google/sanitizers/issues/373
1012
585
  // We can't make this conditional on -fsanitize=leak, as that flag shouldn't
1013
585
  // affect compilation.
1014
585
  if (Sanitizers.has(SanitizerKind::Memory) ||
1015
585
      
Sanitizers.has(SanitizerKind::Address)540
)
1016
201
    CmdArgs.push_back("-fno-assume-sane-operator-new");
1017
585
1018
585
  // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
1019
585
  // enabled.
1020
585
  if (Sanitizers.hasOneOf(CFIClasses) && 
!TC.getTriple().isOSWindows()39
&&
1021
585
      
!Args.hasArg(options::OPT_fvisibility_EQ)34
) {
1022
18
    TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
1023
18
        << lastArgumentForMask(TC.getDriver(), Args,
1024
18
                               Sanitizers.Mask & CFIClasses)
1025
18
        << "-fvisibility=";
1026
18
  }
1027
585
}
1028
1029
SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
1030
2.55k
                             bool DiagnoseErrors) {
1031
2.55k
  assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
1032
2.55k
          A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1033
2.55k
          A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1034
2.55k
          A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1035
2.55k
          A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1036
2.55k
          A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
1037
2.55k
         "Invalid argument in parseArgValues!");
1038
2.55k
  SanitizerMask Kinds;
1039
5.25k
  for (int i = 0, n = A->getNumValues(); i != n; 
++i2.69k
) {
1040
2.69k
    const char *Value = A->getValue(i);
1041
2.69k
    SanitizerMask Kind;
1042
2.69k
    // Special case: don't accept -fsanitize=all.
1043
2.69k
    if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
1044
2.69k
        
0 == strcmp("all", Value)858
)
1045
1
      Kind = SanitizerMask();
1046
2.69k
    else
1047
2.69k
      Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
1048
2.69k
1049
2.69k
    if (Kind)
1050
2.69k
      Kinds |= Kind;
1051
4
    else if (DiagnoseErrors)
1052
4
      D.Diag(clang::diag::err_drv_unsupported_option_argument)
1053
4
          << A->getOption().getName() << Value;
1054
2.69k
  }
1055
2.55k
  return Kinds;
1056
2.55k
}
1057
1058
56
int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
1059
56
  assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
1060
56
         A->getOption().matches(options::OPT_fno_sanitize_coverage));
1061
56
  int Features = 0;
1062
147
  for (int i = 0, n = A->getNumValues(); i != n; 
++i91
) {
1063
91
    const char *Value = A->getValue(i);
1064
91
    int F = llvm::StringSwitch<int>(Value)
1065
91
        .Case("func", CoverageFunc)
1066
91
        .Case("bb", CoverageBB)
1067
91
        .Case("edge", CoverageEdge)
1068
91
        .Case("indirect-calls", CoverageIndirCall)
1069
91
        .Case("trace-bb", CoverageTraceBB)
1070
91
        .Case("trace-cmp", CoverageTraceCmp)
1071
91
        .Case("trace-div", CoverageTraceDiv)
1072
91
        .Case("trace-gep", CoverageTraceGep)
1073
91
        .Case("8bit-counters", Coverage8bitCounters)
1074
91
        .Case("trace-pc", CoverageTracePC)
1075
91
        .Case("trace-pc-guard", CoverageTracePCGuard)
1076
91
        .Case("no-prune", CoverageNoPrune)
1077
91
        .Case("inline-8bit-counters", CoverageInline8bitCounters)
1078
91
        .Case("pc-table", CoveragePCTable)
1079
91
        .Case("stack-depth", CoverageStackDepth)
1080
91
        .Default(0);
1081
91
    if (F == 0)
1082
1
      D.Diag(clang::diag::err_drv_unsupported_option_argument)
1083
1
          << A->getOption().getName() << Value;
1084
91
    Features |= F;
1085
91
  }
1086
56
  return Features;
1087
56
}
1088
1089
std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
1090
116
                                SanitizerMask Mask) {
1091
116
  for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
1092
116
                                                  E = Args.rend();
1093
600
       I != E; 
++I484
) {
1094
600
    const auto *Arg = *I;
1095
600
    if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
1096
117
      SanitizerMask AddKinds =
1097
117
          expandSanitizerGroups(parseArgValues(D, Arg, false));
1098
117
      if (AddKinds & Mask)
1099
116
        return describeSanitizeArg(Arg, Mask);
1100
483
    } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1101
0
      SanitizerMask RemoveKinds =
1102
0
          expandSanitizerGroups(parseArgValues(D, Arg, false));
1103
0
      Mask &= ~RemoveKinds;
1104
0
    }
1105
600
  }
1106
116
  
llvm_unreachable0
("arg list didn't provide expected value");
1107
116
}
1108
1109
147
std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
1110
147
  assert(A->getOption().matches(options::OPT_fsanitize_EQ)
1111
147
         && "Invalid argument in describeSanitizerArg!");
1112
147
1113
147
  std::string Sanitizers;
1114
365
  for (int i = 0, n = A->getNumValues(); i != n; 
++i218
) {
1115
218
    if (expandSanitizerGroups(
1116
218
            parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
1117
218
        Mask) {
1118
147
      if (!Sanitizers.empty())
1119
0
        Sanitizers += ",";
1120
147
      Sanitizers += A->getValue(i);
1121
147
    }
1122
218
  }
1123
147
1124
147
  assert(!Sanitizers.empty() && "arg didn't provide expected value");
1125
147
  return "-fsanitize=" + Sanitizers;
1126
147
}