Coverage Report

Created: 2023-09-12 09:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- FreeBSD.cpp - FreeBSD ToolChain Implementations --------*- C++ -*-===//
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
9
#include "FreeBSD.h"
10
#include "Arch/ARM.h"
11
#include "Arch/Mips.h"
12
#include "Arch/Sparc.h"
13
#include "CommonArgs.h"
14
#include "clang/Config/config.h"
15
#include "clang/Driver/Compilation.h"
16
#include "clang/Driver/DriverDiagnostic.h"
17
#include "clang/Driver/Options.h"
18
#include "clang/Driver/SanitizerArgs.h"
19
#include "llvm/Option/ArgList.h"
20
#include "llvm/Support/VirtualFileSystem.h"
21
22
using namespace clang::driver;
23
using namespace clang::driver::tools;
24
using namespace clang::driver::toolchains;
25
using namespace clang;
26
using namespace llvm::opt;
27
28
void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
29
                                      const InputInfo &Output,
30
                                      const InputInfoList &Inputs,
31
                                      const ArgList &Args,
32
22
                                      const char *LinkingOutput) const {
33
22
  claimNoWarnArgs(Args);
34
22
  ArgStringList CmdArgs;
35
22
  const auto &D = getToolChain().getDriver();
36
37
  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
38
  // instruct as in the base system to assemble 32-bit code.
39
22
  switch (getToolChain().getArch()) {
40
0
  default:
41
0
    break;
42
0
  case llvm::Triple::x86:
43
0
    CmdArgs.push_back("--32");
44
0
    break;
45
0
  case llvm::Triple::ppc:
46
0
  case llvm::Triple::ppcle:
47
0
    CmdArgs.push_back("-a32");
48
0
    break;
49
9
  case llvm::Triple::mips:
50
11
  case llvm::Triple::mipsel:
51
15
  case llvm::Triple::mips64:
52
17
  case llvm::Triple::mips64el: {
53
17
    StringRef CPUName;
54
17
    StringRef ABIName;
55
17
    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
56
57
17
    CmdArgs.push_back("-march");
58
17
    CmdArgs.push_back(CPUName.data());
59
60
17
    CmdArgs.push_back("-mabi");
61
17
    CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
62
63
17
    if (getToolChain().getTriple().isLittleEndian())
64
4
      CmdArgs.push_back("-EL");
65
13
    else
66
13
      CmdArgs.push_back("-EB");
67
68
17
    if (Arg *A = Args.getLastArg(options::OPT_G)) {
69
1
      StringRef v = A->getValue();
70
1
      CmdArgs.push_back(Args.MakeArgString("-G" + v));
71
1
      A->claim();
72
1
    }
73
74
17
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
75
17
    break;
76
15
  }
77
3
  case llvm::Triple::arm:
78
3
  case llvm::Triple::armeb:
79
3
  case llvm::Triple::thumb:
80
3
  case llvm::Triple::thumbeb: {
81
3
    arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
82
83
3
    if (ABI == arm::FloatABI::Hard)
84
1
      CmdArgs.push_back("-mfpu=vfp");
85
2
    else
86
2
      CmdArgs.push_back("-mfpu=softvfp");
87
88
3
    CmdArgs.push_back("-meabi=5");
89
3
    break;
90
3
  }
91
1
  case llvm::Triple::sparc:
92
1
  case llvm::Triple::sparcel:
93
2
  case llvm::Triple::sparcv9: {
94
2
    std::string CPU = getCPUName(D, Args, getToolChain().getTriple());
95
2
    CmdArgs.push_back(
96
2
        sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
97
2
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
98
2
    break;
99
1
  }
100
22
  }
101
102
22
  for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
103
22
                                    options::OPT_fdebug_prefix_map_EQ)) {
104
0
    StringRef Map = A->getValue();
105
0
    if (!Map.contains('='))
106
0
      D.Diag(diag::err_drv_invalid_argument_to_option)
107
0
          << Map << A->getOption().getName();
108
0
    else {
109
0
      CmdArgs.push_back(Args.MakeArgString("--debug-prefix-map"));
110
0
      CmdArgs.push_back(Args.MakeArgString(Map));
111
0
    }
112
0
    A->claim();
113
0
  }
114
115
22
  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
116
117
22
  CmdArgs.push_back("-o");
118
22
  CmdArgs.push_back(Output.getFilename());
119
120
22
  for (const auto &II : Inputs)
121
22
    CmdArgs.push_back(II.getFilename());
122
123
22
  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
124
22
  C.addCommand(std::make_unique<Command>(JA, *this,
125
22
                                         ResponseFileSupport::AtFileCurCP(),
126
22
                                         Exec, CmdArgs, Inputs, Output));
127
22
}
128
129
void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
130
                                   const InputInfo &Output,
131
                                   const InputInfoList &Inputs,
132
                                   const ArgList &Args,
133
88
                                   const char *LinkingOutput) const {
134
88
  const toolchains::FreeBSD &ToolChain =
135
88
      static_cast<const toolchains::FreeBSD &>(getToolChain());
136
88
  const Driver &D = ToolChain.getDriver();
137
88
  const llvm::Triple::ArchType Arch = ToolChain.getArch();
138
88
  const bool IsPIE =
139
88
      !Args.hasArg(options::OPT_shared) &&
140
88
      
(86
Args.hasArg(options::OPT_pie)86
||
ToolChain.isPIEDefault(Args)84
);
141
88
  ArgStringList CmdArgs;
142
143
  // Silence warning for "clang -g foo.o -o foo"
144
88
  Args.ClaimAllArgs(options::OPT_g_Group);
145
  // and "clang -emit-llvm foo.o -o foo"
146
88
  Args.ClaimAllArgs(options::OPT_emit_llvm);
147
  // and for "clang -w foo.o -o foo". Other warning options are already
148
  // handled somewhere else.
149
88
  Args.ClaimAllArgs(options::OPT_w);
150
151
88
  if (!D.SysRoot.empty())
152
32
    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
153
154
88
  if (IsPIE)
155
2
    CmdArgs.push_back("-pie");
156
157
88
  CmdArgs.push_back("--eh-frame-hdr");
158
88
  if (Args.hasArg(options::OPT_static)) {
159
2
    CmdArgs.push_back("-Bstatic");
160
86
  } else {
161
86
    if (Args.hasArg(options::OPT_rdynamic))
162
0
      CmdArgs.push_back("-export-dynamic");
163
86
    if (Args.hasArg(options::OPT_shared)) {
164
2
      CmdArgs.push_back("-shared");
165
84
    } else if (!Args.hasArg(options::OPT_r)) {
166
83
      CmdArgs.push_back("-dynamic-linker");
167
83
      CmdArgs.push_back("/libexec/ld-elf.so.1");
168
83
    }
169
86
    const llvm::Triple &T = ToolChain.getTriple();
170
86
    if (Arch == llvm::Triple::arm || 
Arch == llvm::Triple::sparc82
||
T.isX86()81
)
171
53
      CmdArgs.push_back("--hash-style=both");
172
86
    CmdArgs.push_back("--enable-new-dtags");
173
86
  }
174
175
  // Explicitly set the linker emulation for platforms that might not
176
  // be the default emulation for the linker.
177
88
  switch (Arch) {
178
6
  case llvm::Triple::x86:
179
6
    CmdArgs.push_back("-m");
180
6
    CmdArgs.push_back("elf_i386_fbsd");
181
6
    break;
182
2
  case llvm::Triple::ppc:
183
2
    CmdArgs.push_back("-m");
184
2
    CmdArgs.push_back("elf32ppc_fbsd");
185
2
    break;
186
1
  case llvm::Triple::ppcle:
187
1
    CmdArgs.push_back("-m");
188
    // Use generic -- only usage is for freestanding.
189
1
    CmdArgs.push_back("elf32lppc");
190
1
    break;
191
4
  case llvm::Triple::mips:
192
4
    CmdArgs.push_back("-m");
193
4
    CmdArgs.push_back("elf32btsmip_fbsd");
194
4
    break;
195
2
  case llvm::Triple::mipsel:
196
2
    CmdArgs.push_back("-m");
197
2
    CmdArgs.push_back("elf32ltsmip_fbsd");
198
2
    break;
199
4
  case llvm::Triple::mips64:
200
4
    CmdArgs.push_back("-m");
201
4
    if (tools::mips::hasMipsAbiArg(Args, "n32"))
202
1
      CmdArgs.push_back("elf32btsmipn32_fbsd");
203
3
    else
204
3
      CmdArgs.push_back("elf64btsmip_fbsd");
205
4
    break;
206
3
  case llvm::Triple::mips64el:
207
3
    CmdArgs.push_back("-m");
208
3
    if (tools::mips::hasMipsAbiArg(Args, "n32"))
209
1
      CmdArgs.push_back("elf32ltsmipn32_fbsd");
210
2
    else
211
2
      CmdArgs.push_back("elf64ltsmip_fbsd");
212
3
    break;
213
1
  case llvm::Triple::riscv32:
214
1
    CmdArgs.push_back("-m");
215
1
    CmdArgs.push_back("elf32lriscv");
216
1
    CmdArgs.push_back("-X");
217
1
    break;
218
2
  case llvm::Triple::riscv64:
219
2
    CmdArgs.push_back("-m");
220
2
    CmdArgs.push_back("elf64lriscv");
221
2
    CmdArgs.push_back("-X");
222
2
    break;
223
63
  default:
224
63
    break;
225
88
  }
226
227
88
  if (Arg *A = Args.getLastArg(options::OPT_G)) {
228
1
    if (ToolChain.getTriple().isMIPS()) {
229
1
      StringRef v = A->getValue();
230
1
      CmdArgs.push_back(Args.MakeArgString("-G" + v));
231
1
      A->claim();
232
1
    }
233
1
  }
234
235
88
  if (Output.isFilename()) {
236
88
    CmdArgs.push_back("-o");
237
88
    CmdArgs.push_back(Output.getFilename());
238
88
  } else {
239
0
    assert(Output.isNothing() && "Invalid output.");
240
0
  }
241
242
88
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
243
88
                   options::OPT_r)) {
244
84
    const char *crt1 = nullptr;
245
84
    if (!Args.hasArg(options::OPT_shared)) {
246
82
      if (Args.hasArg(options::OPT_pg))
247
3
        crt1 = "gcrt1.o";
248
79
      else if (IsPIE)
249
2
        crt1 = "Scrt1.o";
250
77
      else
251
77
        crt1 = "crt1.o";
252
82
    }
253
84
    if (crt1)
254
82
      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
255
256
84
    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
257
258
84
    const char *crtbegin = nullptr;
259
84
    if (Args.hasArg(options::OPT_static))
260
2
      crtbegin = "crtbeginT.o";
261
82
    else if (Args.hasArg(options::OPT_shared) || 
IsPIE80
)
262
4
      crtbegin = "crtbeginS.o";
263
78
    else
264
78
      crtbegin = "crtbegin.o";
265
266
84
    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
267
84
  }
268
269
88
  Args.AddAllArgs(CmdArgs, options::OPT_L);
270
88
  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
271
88
  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
272
88
  Args.AddAllArgs(CmdArgs, options::OPT_s);
273
88
  Args.AddAllArgs(CmdArgs, options::OPT_t);
274
88
  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
275
88
  Args.AddAllArgs(CmdArgs, options::OPT_r);
276
277
88
  if (D.isUsingLTO()) {
278
0
    assert(!Inputs.empty() && "Must have at least one input.");
279
0
    addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0],
280
0
                  D.getLTOMode() == LTOK_Thin);
281
0
  }
282
283
88
  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
284
88
  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
285
88
  addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs);
286
88
  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
287
288
88
  unsigned Major = ToolChain.getTriple().getOSMajorVersion();
289
88
  bool Profiling = Args.hasArg(options::OPT_pg) && 
Major != 03
&&
Major < 142
;
290
88
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
291
88
                   options::OPT_r)) {
292
    // Use the static OpenMP runtime with -static-openmp
293
84
    bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
294
84
                        
!Args.hasArg(options::OPT_static)4
;
295
84
    addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
296
297
84
    if (D.CCCIsCXX()) {
298
5
      if (ToolChain.ShouldLinkCXXStdlib(Args))
299
5
        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
300
5
      if (Profiling)
301
1
        CmdArgs.push_back("-lm_p");
302
4
      else
303
4
        CmdArgs.push_back("-lm");
304
5
    }
305
84
    if (NeedsSanitizerDeps)
306
4
      linkSanitizerRuntimeDeps(ToolChain, Args, CmdArgs);
307
84
    if (NeedsXRayDeps)
308
0
      linkXRayRuntimeDeps(ToolChain, Args, CmdArgs);
309
    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
310
    // the default system libraries. Just mimic this for now.
311
84
    if (Profiling)
312
1
      CmdArgs.push_back("-lgcc_p");
313
83
    else
314
83
      CmdArgs.push_back("-lgcc");
315
84
    if (Args.hasArg(options::OPT_static)) {
316
2
      CmdArgs.push_back("-lgcc_eh");
317
82
    } else if (Profiling) {
318
1
      CmdArgs.push_back("-lgcc_eh_p");
319
81
    } else {
320
81
      CmdArgs.push_back("--as-needed");
321
81
      CmdArgs.push_back("-lgcc_s");
322
81
      CmdArgs.push_back("--no-as-needed");
323
81
    }
324
325
84
    if (Args.hasArg(options::OPT_pthread)) {
326
0
      if (Profiling)
327
0
        CmdArgs.push_back("-lpthread_p");
328
0
      else
329
0
        CmdArgs.push_back("-lpthread");
330
0
    }
331
332
84
    if (Profiling) {
333
1
      if (Args.hasArg(options::OPT_shared))
334
0
        CmdArgs.push_back("-lc");
335
1
      else
336
1
        CmdArgs.push_back("-lc_p");
337
1
      CmdArgs.push_back("-lgcc_p");
338
83
    } else {
339
83
      CmdArgs.push_back("-lc");
340
83
      CmdArgs.push_back("-lgcc");
341
83
    }
342
343
84
    if (Args.hasArg(options::OPT_static)) {
344
2
      CmdArgs.push_back("-lgcc_eh");
345
82
    } else if (Profiling) {
346
1
      CmdArgs.push_back("-lgcc_eh_p");
347
81
    } else {
348
81
      CmdArgs.push_back("--as-needed");
349
81
      CmdArgs.push_back("-lgcc_s");
350
81
      CmdArgs.push_back("--no-as-needed");
351
81
    }
352
84
  }
353
354
88
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
355
88
                   options::OPT_r)) {
356
84
    if (Args.hasArg(options::OPT_shared) || 
IsPIE82
)
357
4
      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
358
80
    else
359
80
      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
360
84
    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
361
84
  }
362
363
88
  ToolChain.addProfileRTLibs(Args, CmdArgs);
364
365
88
  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
366
88
  C.addCommand(std::make_unique<Command>(JA, *this,
367
88
                                         ResponseFileSupport::AtFileCurCP(),
368
88
                                         Exec, CmdArgs, Inputs, Output));
369
88
}
370
371
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
372
373
FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
374
                 const ArgList &Args)
375
146
    : Generic_ELF(D, Triple, Args) {
376
377
  // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
378
  // back to '/usr/lib' if it doesn't exist.
379
146
  if (Triple.isArch32Bit() &&
380
146
      
D.getVFS().exists(concat(getDriver().SysRoot, "/usr/lib32/crt1.o"))47
)
381
5
    getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib32"));
382
141
  else
383
141
    getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib"));
384
146
}
385
386
14
unsigned FreeBSD::GetDefaultDwarfVersion() const {
387
14
  unsigned Major = getTriple().getOSMajorVersion();
388
14
  if (Major >= 12 || 
Major == 013
)
389
7
    return 4;
390
7
  return 2;
391
14
}
392
393
void FreeBSD::AddClangSystemIncludeArgs(
394
    const llvm::opt::ArgList &DriverArgs,
395
149
    llvm::opt::ArgStringList &CC1Args) const {
396
149
  const Driver &D = getDriver();
397
398
149
  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
399
0
    return;
400
401
149
  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
402
149
    SmallString<128> Dir(D.ResourceDir);
403
149
    llvm::sys::path::append(Dir, "include");
404
149
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
405
149
  }
406
407
149
  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
408
0
    return;
409
410
  // Check for configure-time C include directories.
411
149
  StringRef CIncludeDirs(C_INCLUDE_DIRS);
412
149
  if (CIncludeDirs != "") {
413
0
    SmallVector<StringRef, 5> dirs;
414
0
    CIncludeDirs.split(dirs, ":");
415
0
    for (StringRef dir : dirs) {
416
0
      StringRef Prefix =
417
0
          llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : "";
418
0
      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
419
0
    }
420
0
    return;
421
0
  }
422
423
149
  addExternCSystemInclude(DriverArgs, CC1Args,
424
149
                          concat(D.SysRoot, "/usr/include"));
425
149
}
426
427
void FreeBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
428
10
                                    llvm::opt::ArgStringList &CC1Args) const {
429
10
  addSystemInclude(DriverArgs, CC1Args,
430
10
                   concat(getDriver().SysRoot, "/usr/include/c++/v1"));
431
10
}
432
433
void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
434
5
                                  ArgStringList &CmdArgs) const {
435
5
  unsigned Major = getTriple().getOSMajorVersion();
436
5
  bool Profiling = Args.hasArg(options::OPT_pg) && 
Major != 03
&&
Major < 142
;
437
438
5
  CmdArgs.push_back(Profiling ? 
"-lc++_p"1
:
"-lc++"4
);
439
5
  if (Args.hasArg(options::OPT_fexperimental_library))
440
0
    CmdArgs.push_back("-lc++experimental");
441
5
}
442
443
void FreeBSD::AddCudaIncludeArgs(const ArgList &DriverArgs,
444
0
                                 ArgStringList &CC1Args) const {
445
0
  CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args);
446
0
}
447
448
void FreeBSD::AddHIPIncludeArgs(const ArgList &DriverArgs,
449
0
                                ArgStringList &CC1Args) const {
450
0
  RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
451
0
}
452
453
22
Tool *FreeBSD::buildAssembler() const {
454
22
  return new tools::freebsd::Assembler(*this);
455
22
}
456
457
88
Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
458
459
97
bool FreeBSD::HasNativeLLVMSupport() const { return true; }
460
461
ToolChain::UnwindTableLevel
462
302
FreeBSD::getDefaultUnwindTableLevel(const ArgList &Args) const {
463
302
  return UnwindTableLevel::Asynchronous;
464
302
}
465
466
297
bool FreeBSD::isPIEDefault(const llvm::opt::ArgList &Args) const {
467
297
  return getSanitizerArgs(Args).requiresPIE();
468
297
}
469
470
624
SanitizerMask FreeBSD::getSupportedSanitizers() const {
471
624
  const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64;
472
624
  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
473
624
  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
474
624
  const bool IsMIPS64 = getTriple().isMIPS64();
475
624
  SanitizerMask Res = ToolChain::getSupportedSanitizers();
476
624
  Res |= SanitizerKind::Address;
477
624
  Res |= SanitizerKind::PointerCompare;
478
624
  Res |= SanitizerKind::PointerSubtract;
479
624
  Res |= SanitizerKind::Vptr;
480
624
  if (IsAArch64 || 
IsX86_64598
||
IsMIPS64351
) {
481
357
    Res |= SanitizerKind::Leak;
482
357
    Res |= SanitizerKind::Thread;
483
357
  }
484
624
  if (IsAArch64 || 
IsX86598
||
IsX86_64553
) {
485
318
    Res |= SanitizerKind::SafeStack;
486
318
    Res |= SanitizerKind::Fuzzer;
487
318
    Res |= SanitizerKind::FuzzerNoLink;
488
318
  }
489
624
  if (IsAArch64 || 
IsX86_64598
) {
490
273
    Res |= SanitizerKind::KernelAddress;
491
273
    Res |= SanitizerKind::KernelMemory;
492
273
    Res |= SanitizerKind::Memory;
493
273
  }
494
624
  return Res;
495
624
}
496
497
void FreeBSD::addClangTargetOptions(const ArgList &DriverArgs,
498
                                    ArgStringList &CC1Args,
499
151
                                    Action::OffloadKind) const {
500
151
  unsigned Major = getTriple().getOSMajorVersion();
501
151
  if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
502
151
                          options::OPT_fno_use_init_array,
503
151
                          (Major >= 12 || 
Major == 0134
)))
504
21
    CC1Args.push_back("-fno-use-init-array");
505
151
}