Bug Summary

File:build/source/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
Warning:line 284, column 15
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name AArch64.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -I tools/clang/lib/Driver -I /build/source/clang/lib/Driver -I /build/source/clang/include -I tools/clang/include -I include -I /build/source/llvm/include -D CLANG_REPOSITORY_STRING="++20230206101206+d453d73d0d04-1~exp1~20230206221324.1090" -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1675721604 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-02-07-030702-17298-1 -x c++ /build/source/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
1//===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- 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 "AArch64.h"
10#include "../CommonArgs.h"
11#include "clang/Driver/Driver.h"
12#include "clang/Driver/DriverDiagnostic.h"
13#include "clang/Driver/Options.h"
14#include "llvm/Option/ArgList.h"
15#include "llvm/Support/Host.h"
16#include "llvm/Support/TargetParser.h"
17#include "llvm/TargetParser/AArch64TargetParser.h"
18
19using namespace clang::driver;
20using namespace clang::driver::tools;
21using namespace clang;
22using namespace llvm::opt;
23
24/// \returns true if the given triple can determine the default CPU type even
25/// if -arch is not specified.
26static bool isCPUDeterminedByTriple(const llvm::Triple &Triple) {
27 return Triple.isOSDarwin();
28}
29
30/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
31/// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is
32/// provided, or to nullptr otherwise.
33std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
34 const llvm::Triple &Triple, Arg *&A) {
35 std::string CPU;
36 // If we have -mcpu, use that.
37 if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
38 StringRef Mcpu = A->getValue();
39 CPU = Mcpu.split("+").first.lower();
40 }
41
42 CPU = llvm::AArch64::resolveCPUAlias(CPU);
43
44 // Handle CPU name is 'native'.
45 if (CPU == "native")
46 return std::string(llvm::sys::getHostCPUName());
47
48 if (CPU.size())
49 return CPU;
50
51 if (Triple.isTargetMachineMac() &&
52 Triple.getArch() == llvm::Triple::aarch64) {
53 // Apple Silicon macs default to M1 CPUs.
54 return "apple-m1";
55 }
56
57 // arm64e requires v8.3a and only runs on apple-a12 and later CPUs.
58 if (Triple.isArm64e())
59 return "apple-a12";
60
61 // Make sure we pick the appropriate Apple CPU if -arch is used or when
62 // targetting a Darwin OS.
63 if (Args.getLastArg(options::OPT_arch) || Triple.isOSDarwin())
64 return Triple.getArch() == llvm::Triple::aarch64_32 ? "apple-s4"
65 : "apple-a7";
66
67 return "generic";
68}
69
70// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
71static bool DecodeAArch64Features(const Driver &D, StringRef text,
72 std::vector<StringRef> &Features,
73 const llvm::AArch64::ArchInfo &ArchInfo) {
74 SmallVector<StringRef, 8> Split;
75 text.split(Split, StringRef("+"), -1, false);
76
77 for (StringRef Feature : Split) {
78 StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
79 if (!FeatureName.empty())
80 Features.push_back(FeatureName);
81 else if (Feature == "neon" || Feature == "noneon")
82 D.Diag(clang::diag::err_drv_no_neon_modifier);
83 else
84 return false;
85
86 if (Feature == "sve2")
87 Features.push_back("+sve");
88 else if (Feature == "sve2-bitperm" || Feature == "sve2-sha3" ||
89 Feature == "sve2-aes" || Feature == "sve2-sm4") {
90 Features.push_back("+sve");
91 Features.push_back("+sve2");
92 } else if (Feature == "nosve") {
93 Features.push_back("-sve2");
94 Features.push_back("-sve2-bitperm");
95 Features.push_back("-sve2-sha3");
96 Features.push_back("-sve2-aes");
97 Features.push_back("-sve2-sm4");
98 } else if (Feature == "nosve2") {
99 Features.push_back("-sve2-bitperm");
100 Features.push_back("-sve2-sha3");
101 Features.push_back("-sve2-aes");
102 Features.push_back("-sve2-sm4");
103 }
104
105 // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A)
106 // It isn't the case in general that sve implies both f64mm and f32mm
107 if ((ArchInfo == llvm::AArch64::ARMV8_6A ||
108 ArchInfo == llvm::AArch64::ARMV8_7A ||
109 ArchInfo == llvm::AArch64::ARMV8_8A ||
110 ArchInfo == llvm::AArch64::ARMV8_9A ||
111 ArchInfo == llvm::AArch64::ARMV9_1A ||
112 ArchInfo == llvm::AArch64::ARMV9_2A ||
113 ArchInfo == llvm::AArch64::ARMV9_3A ||
114 ArchInfo == llvm::AArch64::ARMV9_4A) &&
115 Feature == "sve")
116 Features.push_back("+f32mm");
117 }
118 return true;
119}
120
121// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
122// decode CPU and feature.
123static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
124 std::vector<StringRef> &Features) {
125 std::pair<StringRef, StringRef> Split = Mcpu.split("+");
126 CPU = Split.first;
127 const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
128
129 if (CPU == "native")
130 CPU = llvm::sys::getHostCPUName();
131
132 if (CPU == "generic") {
133 Features.push_back("+neon");
134 } else {
135 const std::optional<llvm::AArch64::CpuInfo> CpuInfo =
136 llvm::AArch64::parseCpu(CPU);
137 if (!CpuInfo)
138 return false;
139 ArchInfo = &CpuInfo->Arch;
140
141 Features.push_back(ArchInfo->ArchFeature);
142
143 uint64_t Extension = CpuInfo->getImpliedExtensions();
144 if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
145 return false;
146 }
147
148 if (Split.second.size() &&
149 !DecodeAArch64Features(D, Split.second, Features, *ArchInfo))
150 return false;
151
152 return true;
153}
154
155static bool
156getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
157 const ArgList &Args,
158 std::vector<StringRef> &Features) {
159 std::string MarchLowerCase = March.lower();
160 std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
161
162 std::optional <llvm::AArch64::ArchInfo> ArchInfo =
163 llvm::AArch64::parseArch(Split.first);
164 if (Split.first == "native")
13
Assuming the condition is false
14
Taking false branch
165 ArchInfo = llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str());
166 if (!ArchInfo)
15
Assuming the condition is false
16
Taking false branch
167 return false;
168 Features.push_back(ArchInfo->ArchFeature);
169
170 // Enable SVE2 by default on Armv9-A.
171 // It can still be disabled if +nosve2 is present.
172 // We must do this early so that DecodeAArch64Features has the correct state
173 if ((*ArchInfo == llvm::AArch64::ARMV9A ||
17
Assuming the condition is false
174 *ArchInfo == llvm::AArch64::ARMV9_1A ||
18
Assuming the condition is false
175 *ArchInfo == llvm::AArch64::ARMV9_2A)) {
19
Assuming the condition is false
176 Features.push_back("+sve");
177 Features.push_back("+sve2");
178 }
179
180 if ((Split.second.size() &&
20
Assuming the condition is true
21
Taking true branch
181 !DecodeAArch64Features(D, Split.second, Features, *ArchInfo)))
182 return false;
22
Returning zero, which participates in a condition later
183
184 return true;
185}
186
187static bool
188getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
189 const ArgList &Args,
190 std::vector<StringRef> &Features) {
191 StringRef CPU;
192 std::string McpuLowerCase = Mcpu.lower();
193 if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
194 return false;
195
196 return true;
197}
198
199static bool
200getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
201 const ArgList &Args,
202 std::vector<StringRef> &Features) {
203 std::string MtuneLowerCase = Mtune.lower();
204 // Check CPU name is valid
205 std::vector<StringRef> MtuneFeatures;
206 StringRef Tune;
207 if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, MtuneFeatures))
208 return false;
209
210 // Handle CPU name is 'native'.
211 if (MtuneLowerCase == "native")
212 MtuneLowerCase = std::string(llvm::sys::getHostCPUName());
213 if (MtuneLowerCase == "cyclone" ||
214 StringRef(MtuneLowerCase).startswith("apple")) {
215 Features.push_back("+zcm");
216 Features.push_back("+zcz");
217 }
218 return true;
219}
220
221static bool
222getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
223 const ArgList &Args,
224 std::vector<StringRef> &Features) {
225 StringRef CPU;
226 std::vector<StringRef> DecodedFeature;
227 std::string McpuLowerCase = Mcpu.lower();
228 if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
229 return false;
230
231 return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
232}
233
234void aarch64::getAArch64TargetFeatures(const Driver &D,
235 const llvm::Triple &Triple,
236 const ArgList &Args,
237 std::vector<StringRef> &Features,
238 bool ForAS) {
239 Arg *A;
240 bool success = true;
241 // Enable NEON by default.
242 Features.push_back("+neon");
243 llvm::StringRef WaMArch;
244 if (ForAS)
1
Assuming 'ForAS' is false
2
Taking false branch
245 for (const auto *A :
246 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
247 for (StringRef Value : A->getValues())
248 if (Value.startswith("-march="))
249 WaMArch = Value.substr(7);
250 // Call getAArch64ArchFeaturesFromMarch only if "-Wa,-march=" or
251 // "-Xassembler -march" is detected. Otherwise it may return false
252 // and causes Clang to error out.
253 if (!WaMArch.empty())
3
Assuming the condition is false
4
Taking false branch
254 success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Features);
255 else if ((A = Args.getLastArg(options::OPT_march_EQ)))
5
Assuming 'A' is null
6
Taking false branch
256 success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
257 else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
7
Value assigned to 'A'
8
Assuming 'A' is null
9
Assuming pointer value is null
258 success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
259 else if (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple))
10
Assuming the condition is false
11
Taking false branch
260 success = getAArch64ArchFeaturesFromMcpu(
261 D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
262 else
263 // Default to 'A' profile if the architecture is not specified.
264 success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Features);
12
Calling 'getAArch64ArchFeaturesFromMarch'
23
Returning from 'getAArch64ArchFeaturesFromMarch'
265
266 if (success
23.1
'success' is false
&& (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
267 success =
268 getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
269 else if (success
23.2
'success' is false
&& (A = Args.getLastArg(options::OPT_mcpu_EQ)))
270 success =
271 getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
272 else if (success
23.3
'success' is false
&&
273 (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple)))
274 success = getAArch64MicroArchFeaturesFromMcpu(
275 D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
276
277 if (!success
23.4
'success' is false
) {
24
Taking true branch
278 auto Diag = D.Diag(diag::err_drv_unsupported_option_argument);
279 // If "-Wa,-march=" is used, 'WaMArch' will contain the argument's value,
280 // while 'A' is uninitialized. Only dereference 'A' in the other case.
281 if (!WaMArch.empty())
25
Assuming the condition is false
26
Taking false branch
282 Diag << "-march=" << WaMArch;
283 else
284 Diag << A->getSpelling() << A->getValue();
27
Called C++ object pointer is null
285 }
286
287 if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
288 Features.push_back("-fp-armv8");
289 Features.push_back("-crypto");
290 Features.push_back("-neon");
291 }
292
293 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
294 StringRef Mtp = A->getValue();
295 if (Mtp == "el3")
296 Features.push_back("+tpidr-el3");
297 else if (Mtp == "el2")
298 Features.push_back("+tpidr-el2");
299 else if (Mtp == "el1")
300 Features.push_back("+tpidr-el1");
301 else if (Mtp != "el0")
302 D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
303 }
304
305 // Enable/disable straight line speculation hardening.
306 if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
307 StringRef Scope = A->getValue();
308 bool EnableRetBr = false;
309 bool EnableBlr = false;
310 bool DisableComdat = false;
311 if (Scope != "none") {
312 SmallVector<StringRef, 4> Opts;
313 Scope.split(Opts, ",");
314 for (auto Opt : Opts) {
315 Opt = Opt.trim();
316 if (Opt == "all") {
317 EnableBlr = true;
318 EnableRetBr = true;
319 continue;
320 }
321 if (Opt == "retbr") {
322 EnableRetBr = true;
323 continue;
324 }
325 if (Opt == "blr") {
326 EnableBlr = true;
327 continue;
328 }
329 if (Opt == "comdat") {
330 DisableComdat = false;
331 continue;
332 }
333 if (Opt == "nocomdat") {
334 DisableComdat = true;
335 continue;
336 }
337 D.Diag(diag::err_drv_unsupported_option_argument)
338 << A->getSpelling() << Scope;
339 break;
340 }
341 }
342
343 if (EnableRetBr)
344 Features.push_back("+harden-sls-retbr");
345 if (EnableBlr)
346 Features.push_back("+harden-sls-blr");
347 if (DisableComdat) {
348 Features.push_back("+harden-sls-nocomdat");
349 }
350 }
351
352 // En/disable crc
353 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
354 if (A->getOption().matches(options::OPT_mcrc))
355 Features.push_back("+crc");
356 else
357 Features.push_back("-crc");
358 }
359
360 int V8Version = -1;
361 int V9Version = -1;
362 bool HasNoSM4 = false;
363 bool HasNoSHA3 = false;
364 bool HasNoSHA2 = false;
365 bool HasNoAES = false;
366 bool HasSM4 = false;
367 bool HasSHA3 = false;
368 bool HasSHA2 = false;
369 bool HasAES = false;
370 bool HasCrypto = false;
371 bool HasNoCrypto = false;
372 int FullFP16Pos = -1;
373 int NoFullFP16Pos = -1;
374 int FP16FMLPos = -1;
375 int NoFP16FMLPos = -1;
376 int ArchFeatPos = -1;
377
378 for (auto I = Features.begin(), E = Features.end(); I != E; I++) {
379 if (*I == "+v8a") V8Version = 0;
380 else if (*I == "+v8.1a") V8Version = 1;
381 else if (*I == "+v8.2a") V8Version = 2;
382 else if (*I == "+v8.3a") V8Version = 3;
383 else if (*I == "+v8.4a") V8Version = 4;
384 else if (*I == "+v8.5a") V8Version = 5;
385 else if (*I == "+v8.6a") V8Version = 6;
386 else if (*I == "+v8.7a") V8Version = 7;
387 else if (*I == "+v8.8a") V8Version = 8;
388 else if (*I == "+v8.9a") V8Version = 9;
389 else if (*I == "+v9a") V9Version = 0;
390 else if (*I == "+v9.1a") V9Version = 1;
391 else if (*I == "+v9.2a") V9Version = 2;
392 else if (*I == "+v9.3a") V9Version = 3;
393 else if (*I == "+v9.4a") V9Version = 4;
394 else if (*I == "+sm4") HasSM4 = true;
395 else if (*I == "+sha3") HasSHA3 = true;
396 else if (*I == "+sha2") HasSHA2 = true;
397 else if (*I == "+aes") HasAES = true;
398 else if (*I == "-sm4") HasNoSM4 = true;
399 else if (*I == "-sha3") HasNoSHA3 = true;
400 else if (*I == "-sha2") HasNoSHA2 = true;
401 else if (*I == "-aes") HasNoAES = true;
402 else if (*I == "+fp16fml") FP16FMLPos = I - Features.begin();
403 else if (*I == "-fp16fml") NoFP16FMLPos = I - Features.begin();
404 else if (*I == "-fullfp16") NoFullFP16Pos = I - Features.begin();
405 else if (*I == "+fullfp16") FullFP16Pos = I - Features.begin();
406 // Whichever option comes after (right-most option) will win
407 else if (*I == "+crypto") {
408 HasCrypto = true;
409 HasNoCrypto = false;
410 } else if (*I == "-crypto" || *I == "-neon") {
411 HasCrypto = false;
412 HasNoCrypto = true;
413 HasSM4 = HasSHA2 = HasSHA3 = HasAES = false;
414 }
415 // Register the iterator position if this is an architecture feature
416 if (ArchFeatPos == -1 && (V8Version != -1 || V9Version != -1))
417 ArchFeatPos = I - Features.begin();
418 }
419
420 // Handle (arch-dependent) fp16fml/fullfp16 relationship.
421 // FIXME: this fp16fml option handling will be reimplemented after the
422 // TargetParser rewrite.
423 if (V8Version >= 4) {
424 // "-fullfp16" "+fullfp16" && "+fp16fml" "+fullfp16" && no "+fullfp16" "-fp16fml" = "+fp16fml"
425 if (FullFP16Pos > NoFullFP16Pos && FullFP16Pos > FP16FMLPos && FullFP16Pos > NoFP16FMLPos)
426 // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
427 // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
428 Features.push_back("+fp16fml");
429 else
430 goto fp16_fml_fallthrough;
431 } else {
432fp16_fml_fallthrough:
433 // In both of these cases, putting the 'other' feature on the end of the vector will
434 // result in the same effect as placing it immediately after the current feature.
435 // "+fp16fml" "-fullfp16" = "-fp16fml"
436 if (NoFullFP16Pos > FP16FMLPos)
437 Features.push_back("-fp16fml");
438 // "-fullfp16" "+fp16fml" = "+fullfp16"
439 else if (NoFullFP16Pos < FP16FMLPos)
440 Features.push_back("+fullfp16");
441 }
442
443 // FIXME: this needs reimplementation too after the TargetParser rewrite
444 //
445 // Context sensitive meaning of Crypto:
446 // 1) For Arch >= ARMv8.4a: crypto = sm4 + sha3 + sha2 + aes
447 // 2) For Arch <= ARMv8.3a: crypto = sha2 + aes
448 if (V8Version >= 4 || V9Version >= 0) {
449 if (HasCrypto && !HasNoCrypto) {
450 // Check if we have NOT disabled an algorithm with something like:
451 // +crypto, -algorithm
452 // And if "-algorithm" does not occur, we enable that crypto algorithm.
453 if (!HasNoSM4)
454 Features.push_back("+sm4");
455 if (!HasNoSHA3)
456 Features.push_back("+sha3");
457 if (!HasNoSHA2)
458 Features.push_back("+sha2");
459 if (!HasNoAES)
460 Features.push_back("+aes");
461 } else if (HasNoCrypto) {
462 // Check if we have NOT enabled a crypto algorithm with something like:
463 // -crypto, +algorithm
464 // And if "+algorithm" does not occur, we disable that crypto algorithm.
465 if (!HasSM4)
466 Features.push_back("-sm4");
467 if (!HasSHA3)
468 Features.push_back("-sha3");
469 if (!HasSHA2)
470 Features.push_back("-sha2");
471 if (!HasAES)
472 Features.push_back("-aes");
473 }
474 } else {
475 if (HasCrypto && !HasNoCrypto) {
476 if (!HasNoSHA2)
477 Features.push_back("+sha2");
478 if (!HasNoAES)
479 Features.push_back("+aes");
480 } else if (HasNoCrypto) {
481 if (!HasSHA2)
482 Features.push_back("-sha2");
483 if (!HasAES)
484 Features.push_back("-aes");
485 if (V8Version == 2 || V8Version == 3) {
486 Features.push_back("-sm4");
487 Features.push_back("-sha3");
488 }
489 }
490 }
491
492 if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
493 options::OPT_munaligned_access)) {
494 if (A->getOption().matches(options::OPT_mno_unaligned_access))
495 Features.push_back("+strict-align");
496 } else if (Triple.isOSOpenBSD())
497 Features.push_back("+strict-align");
498
499 if (Args.hasArg(options::OPT_ffixed_x1))
500 Features.push_back("+reserve-x1");
501
502 if (Args.hasArg(options::OPT_ffixed_x2))
503 Features.push_back("+reserve-x2");
504
505 if (Args.hasArg(options::OPT_ffixed_x3))
506 Features.push_back("+reserve-x3");
507
508 if (Args.hasArg(options::OPT_ffixed_x4))
509 Features.push_back("+reserve-x4");
510
511 if (Args.hasArg(options::OPT_ffixed_x5))
512 Features.push_back("+reserve-x5");
513
514 if (Args.hasArg(options::OPT_ffixed_x6))
515 Features.push_back("+reserve-x6");
516
517 if (Args.hasArg(options::OPT_ffixed_x7))
518 Features.push_back("+reserve-x7");
519
520 if (Args.hasArg(options::OPT_ffixed_x9))
521 Features.push_back("+reserve-x9");
522
523 if (Args.hasArg(options::OPT_ffixed_x10))
524 Features.push_back("+reserve-x10");
525
526 if (Args.hasArg(options::OPT_ffixed_x11))
527 Features.push_back("+reserve-x11");
528
529 if (Args.hasArg(options::OPT_ffixed_x12))
530 Features.push_back("+reserve-x12");
531
532 if (Args.hasArg(options::OPT_ffixed_x13))
533 Features.push_back("+reserve-x13");
534
535 if (Args.hasArg(options::OPT_ffixed_x14))
536 Features.push_back("+reserve-x14");
537
538 if (Args.hasArg(options::OPT_ffixed_x15))
539 Features.push_back("+reserve-x15");
540
541 if (Args.hasArg(options::OPT_ffixed_x18))
542 Features.push_back("+reserve-x18");
543
544 if (Args.hasArg(options::OPT_ffixed_x20))
545 Features.push_back("+reserve-x20");
546
547 if (Args.hasArg(options::OPT_ffixed_x21))
548 Features.push_back("+reserve-x21");
549
550 if (Args.hasArg(options::OPT_ffixed_x22))
551 Features.push_back("+reserve-x22");
552
553 if (Args.hasArg(options::OPT_ffixed_x23))
554 Features.push_back("+reserve-x23");
555
556 if (Args.hasArg(options::OPT_ffixed_x24))
557 Features.push_back("+reserve-x24");
558
559 if (Args.hasArg(options::OPT_ffixed_x25))
560 Features.push_back("+reserve-x25");
561
562 if (Args.hasArg(options::OPT_ffixed_x26))
563 Features.push_back("+reserve-x26");
564
565 if (Args.hasArg(options::OPT_ffixed_x27))
566 Features.push_back("+reserve-x27");
567
568 if (Args.hasArg(options::OPT_ffixed_x28))
569 Features.push_back("+reserve-x28");
570
571 if (Args.hasArg(options::OPT_ffixed_x30))
572 Features.push_back("+reserve-x30");
573
574 if (Args.hasArg(options::OPT_fcall_saved_x8))
575 Features.push_back("+call-saved-x8");
576
577 if (Args.hasArg(options::OPT_fcall_saved_x9))
578 Features.push_back("+call-saved-x9");
579
580 if (Args.hasArg(options::OPT_fcall_saved_x10))
581 Features.push_back("+call-saved-x10");
582
583 if (Args.hasArg(options::OPT_fcall_saved_x11))
584 Features.push_back("+call-saved-x11");
585
586 if (Args.hasArg(options::OPT_fcall_saved_x12))
587 Features.push_back("+call-saved-x12");
588
589 if (Args.hasArg(options::OPT_fcall_saved_x13))
590 Features.push_back("+call-saved-x13");
591
592 if (Args.hasArg(options::OPT_fcall_saved_x14))
593 Features.push_back("+call-saved-x14");
594
595 if (Args.hasArg(options::OPT_fcall_saved_x15))
596 Features.push_back("+call-saved-x15");
597
598 if (Args.hasArg(options::OPT_fcall_saved_x18))
599 Features.push_back("+call-saved-x18");
600
601 if (Args.hasArg(options::OPT_mno_neg_immediates))
602 Features.push_back("+no-neg-immediates");
603
604 if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
605 options::OPT_mno_fix_cortex_a53_835769)) {
606 if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
607 Features.push_back("+fix-cortex-a53-835769");
608 else
609 Features.push_back("-fix-cortex-a53-835769");
610 } else if (Triple.isAndroid()) {
611 // Enabled A53 errata (835769) workaround by default on android
612 Features.push_back("+fix-cortex-a53-835769");
613 } else if (Triple.isOSFuchsia()) {
614 std::string CPU = getCPUName(D, Args, Triple);
615 if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")
616 Features.push_back("+fix-cortex-a53-835769");
617 }
618
619 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
620 Features.push_back("+no-bti-at-return-twice");
621}