1 //===- unittests/Frontend/CompilerInvocationTest.cpp - CI tests //---------===// 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 "clang/Frontend/CompilerInvocation.h" 10 #include "clang/Frontend/CompilerInstance.h" 11 #include "clang/Frontend/TextDiagnosticBuffer.h" 12 #include "llvm/Support/Host.h" 13 14 #include "gmock/gmock.h" 15 #include "gtest/gtest.h" 16 17 using namespace llvm; 18 using namespace clang; 19 20 using ::testing::Contains; 21 using ::testing::StrEq; 22 23 namespace { 24 class CommandLineTest : public ::testing::Test { 25 public: 26 IntrusiveRefCntPtr<DiagnosticsEngine> Diags; 27 SmallVector<const char *, 32> GeneratedArgs; 28 SmallVector<std::string, 32> GeneratedArgsStorage; 29 CompilerInvocation Invocation; 30 31 const char *operator()(const Twine &Arg) { 32 return GeneratedArgsStorage.emplace_back(Arg.str()).c_str(); 33 } 34 35 CommandLineTest() 36 : Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions(), 37 new TextDiagnosticBuffer())) { 38 } 39 }; 40 41 // Boolean option with a keypath that defaults to true. 42 // The only flag with a negative spelling can set the keypath to false. 43 44 TEST_F(CommandLineTest, BoolOptionDefaultTrueSingleFlagNotPresent) { 45 const char *Args[] = {""}; 46 47 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 48 49 ASSERT_FALSE(Diags->hasErrorOccurred()); 50 ASSERT_TRUE(Invocation.getFrontendOpts().UseTemporary); 51 52 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 53 54 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-temp-file")))); 55 } 56 57 TEST_F(CommandLineTest, BoolOptionDefaultTrueSingleFlagPresent) { 58 const char *Args[] = {"-fno-temp-file"}; 59 60 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 61 62 ASSERT_FALSE(Diags->hasErrorOccurred()); 63 ASSERT_FALSE(Invocation.getFrontendOpts().UseTemporary); 64 65 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 66 67 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fno-temp-file"))); 68 } 69 70 TEST_F(CommandLineTest, BoolOptionDefaultTrueSingleFlagUnknownPresent) { 71 const char *Args[] = {"-ftemp-file"}; 72 73 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 74 75 // Driver-only flag. 76 ASSERT_TRUE(Diags->hasErrorOccurred()); 77 ASSERT_TRUE(Invocation.getFrontendOpts().UseTemporary); 78 } 79 80 // Boolean option with a keypath that defaults to true. 81 // The flag with negative spelling can set the keypath to false. 82 // The flag with positive spelling can reset the keypath to true. 83 84 TEST_F(CommandLineTest, BoolOptionDefaultTruePresentNone) { 85 const char *Args[] = {""}; 86 87 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 88 ASSERT_FALSE(Diags->hasErrorOccurred()); 89 ASSERT_TRUE(Invocation.getCodeGenOpts().Autolink); 90 91 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 92 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fautolink")))); 93 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-autolink")))); 94 } 95 96 TEST_F(CommandLineTest, BoolOptionDefaultTruePresentNegChange) { 97 const char *Args[] = {"-fno-autolink"}; 98 99 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 100 ASSERT_FALSE(Diags->hasErrorOccurred()); 101 ASSERT_FALSE(Invocation.getCodeGenOpts().Autolink); 102 103 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 104 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fno-autolink"))); 105 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fautolink")))); 106 } 107 108 TEST_F(CommandLineTest, BoolOptionDefaultTruePresentPosReset) { 109 const char *Args[] = {"-fautolink"}; 110 111 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 112 ASSERT_TRUE(Diags->hasErrorOccurred()); // Driver-only flag. 113 ASSERT_TRUE(Invocation.getCodeGenOpts().Autolink); 114 } 115 116 // Boolean option with a keypath that defaults to false. 117 // The flag with negative spelling can set the keypath to true. 118 // The flag with positive spelling can reset the keypath to false. 119 120 TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentNone) { 121 const char *Args[] = {""}; 122 123 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 124 ASSERT_FALSE(Diags->hasErrorOccurred()); 125 ASSERT_FALSE(Invocation.getCodeGenOpts().NoInlineLineTables); 126 127 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 128 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-ginline-line-tables")))); 129 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-gno-inline-line-tables")))); 130 } 131 132 TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentNegChange) { 133 const char *Args[] = {"-gno-inline-line-tables"}; 134 135 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 136 ASSERT_FALSE(Diags->hasErrorOccurred()); 137 ASSERT_TRUE(Invocation.getCodeGenOpts().NoInlineLineTables); 138 139 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 140 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-gno-inline-line-tables"))); 141 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-ginline-line-tables")))); 142 } 143 144 TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentPosReset) { 145 const char *Args[] = {"-ginline-line-tables"}; 146 147 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 148 ASSERT_TRUE(Diags->hasErrorOccurred()); // Driver-only flag. 149 ASSERT_FALSE(Invocation.getCodeGenOpts().NoInlineLineTables); 150 } 151 152 // Boolean option with a keypath that defaults to false. 153 // The flag with positive spelling can set the keypath to true. 154 // The flag with negative spelling can reset the keypath to false. 155 156 TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentNoneX) { 157 const char *Args[] = {""}; 158 159 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 160 ASSERT_FALSE(Diags->hasErrorOccurred()); 161 ASSERT_FALSE(Invocation.getCodeGenOpts().CodeViewGHash); 162 163 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 164 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-gcodeview-ghash")))); 165 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-gno-codeview-ghash")))); 166 } 167 168 TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentPosChange) { 169 const char *Args[] = {"-gcodeview-ghash"}; 170 171 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 172 ASSERT_FALSE(Diags->hasErrorOccurred()); 173 ASSERT_TRUE(Invocation.getCodeGenOpts().CodeViewGHash); 174 175 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 176 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-gcodeview-ghash"))); 177 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-gno-codeview-ghash")))); 178 } 179 180 TEST_F(CommandLineTest, BoolOptionDefaultFalsePresentNegReset) { 181 const char *Args[] = {"-gno-codeview-ghash"}; 182 183 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 184 ASSERT_TRUE(Diags->hasErrorOccurred()); // Driver-only flag. 185 ASSERT_FALSE(Invocation.getCodeGenOpts().CodeViewGHash); 186 } 187 188 // Boolean option with a keypath that defaults to an arbitrary expression. 189 // The flag with positive spelling can set the keypath to true. 190 // The flag with negative spelling can set the keypath to false. 191 192 static constexpr unsigned PassManagerDefault = 193 !static_cast<unsigned>(LLVM_ENABLE_NEW_PASS_MANAGER); 194 195 static constexpr const char *PassManagerResetByFlag = 196 LLVM_ENABLE_NEW_PASS_MANAGER ? "-fno-legacy-pass-manager" 197 : "-flegacy-pass-manager"; 198 199 static constexpr const char *PassManagerChangedByFlag = 200 LLVM_ENABLE_NEW_PASS_MANAGER ? "-flegacy-pass-manager" 201 : "-fno-legacy-pass-manager"; 202 203 TEST_F(CommandLineTest, BoolOptionDefaultArbitraryTwoFlagsPresentNone) { 204 const char *Args = {""}; 205 206 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 207 208 ASSERT_FALSE(Diags->hasErrorOccurred()); 209 ASSERT_EQ(Invocation.getCodeGenOpts().LegacyPassManager, PassManagerDefault); 210 211 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 212 213 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq(PassManagerResetByFlag)))); 214 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq(PassManagerChangedByFlag)))); 215 } 216 217 TEST_F(CommandLineTest, BoolOptionDefaultArbitraryTwoFlagsPresentChange) { 218 const char *Args[] = {PassManagerChangedByFlag}; 219 220 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 221 ASSERT_FALSE(Diags->hasErrorOccurred()); 222 ASSERT_EQ(Invocation.getCodeGenOpts().LegacyPassManager, !PassManagerDefault); 223 224 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 225 ASSERT_THAT(GeneratedArgs, Contains(StrEq(PassManagerChangedByFlag))); 226 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq(PassManagerResetByFlag)))); 227 } 228 229 TEST_F(CommandLineTest, BoolOptionDefaultArbitraryTwoFlagsPresentReset) { 230 const char *Args[] = {PassManagerResetByFlag}; 231 232 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 233 ASSERT_FALSE(Diags->hasErrorOccurred()); 234 ASSERT_EQ(Invocation.getCodeGenOpts().LegacyPassManager, PassManagerDefault); 235 236 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 237 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq(PassManagerResetByFlag)))); 238 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq(PassManagerChangedByFlag)))); 239 } 240 241 // Boolean option that gets the CC1Option flag from a let statement (which 242 // is applied **after** the record is defined): 243 // 244 // let Flags = [CC1Option] in { 245 // defm option : BoolOption<...>; 246 // } 247 248 TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentNone) { 249 const char *Args[] = {""}; 250 251 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 252 253 ASSERT_FALSE(Diags->hasErrorOccurred()); 254 ASSERT_FALSE(Invocation.getCodeGenOpts().DebugPassManager); 255 256 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 257 258 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdebug-pass-manager")))); 259 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager")))); 260 } 261 262 TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentPos) { 263 const char *Args[] = {"-fdebug-pass-manager"}; 264 265 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 266 267 ASSERT_FALSE(Diags->hasErrorOccurred()); 268 ASSERT_TRUE(Invocation.getCodeGenOpts().DebugPassManager); 269 270 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 271 272 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fdebug-pass-manager"))); 273 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager")))); 274 } 275 276 TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentNeg) { 277 const char *Args[] = {"-fno-debug-pass-manager"}; 278 279 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 280 281 ASSERT_FALSE(Diags->hasErrorOccurred()); 282 ASSERT_FALSE(Invocation.getCodeGenOpts().DebugPassManager); 283 284 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 285 286 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager")))); 287 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdebug-pass-manager")))); 288 } 289 290 TEST_F(CommandLineTest, CanGenerateCC1CommandLineFlag) { 291 const char *Args[] = {"-fmodules-strict-context-hash"}; 292 293 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 294 295 ASSERT_FALSE(Diags->hasErrorOccurred()); 296 297 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 298 299 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fmodules-strict-context-hash"))); 300 } 301 302 TEST_F(CommandLineTest, CanGenerateCC1CommandLineSeparate) { 303 const char *TripleCStr = "i686-apple-darwin9"; 304 const char *Args[] = {"-triple", TripleCStr}; 305 306 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 307 308 ASSERT_FALSE(Diags->hasErrorOccurred()); 309 310 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 311 312 ASSERT_THAT(GeneratedArgs, Contains(StrEq(TripleCStr))); 313 } 314 315 TEST_F(CommandLineTest, CanGenerateCC1CommandLineSeparateRequiredPresent) { 316 const std::string DefaultTriple = 317 llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); 318 const char *Args[] = {"-triple", DefaultTriple.c_str()}; 319 320 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 321 322 ASSERT_FALSE(Diags->hasErrorOccurred()); 323 324 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 325 326 // Triple should always be emitted even if it is the default 327 ASSERT_THAT(GeneratedArgs, Contains(StrEq(DefaultTriple.c_str()))); 328 } 329 330 TEST_F(CommandLineTest, CanGenerateCC1CommandLineSeparateRequiredAbsent) { 331 const std::string DefaultTriple = 332 llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); 333 const char *Args[] = {""}; 334 335 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 336 337 ASSERT_FALSE(Diags->hasErrorOccurred()); 338 339 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 340 341 // Triple should always be emitted even if it is the default 342 ASSERT_THAT(GeneratedArgs, Contains(StrEq(DefaultTriple.c_str()))); 343 } 344 345 TEST_F(CommandLineTest, CanGenerateCC1CommandLineSeparateEnumNonDefault) { 346 const char *Args[] = {"-mrelocation-model", "static"}; 347 348 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 349 350 ASSERT_FALSE(Diags->hasErrorOccurred()); 351 352 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 353 354 // Non default relocation model. 355 ASSERT_THAT(GeneratedArgs, Contains(StrEq("static"))); 356 } 357 358 TEST_F(CommandLineTest, CanGenerateCC1COmmandLineSeparateEnumDefault) { 359 const char *Args[] = {"-mrelocation-model", "pic"}; 360 361 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 362 363 ASSERT_FALSE(Diags->hasErrorOccurred()); 364 365 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 366 367 // Default relocation model. 368 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("pic")))); 369 } 370 371 // Tree of boolean options that can be (directly or transitively) implied by 372 // their parent: 373 // 374 // * -cl-unsafe-math-optimizations 375 // * -cl-mad-enable 376 // * -menable-unsafe-fp-math 377 // * -freciprocal-math 378 379 TEST_F(CommandLineTest, ImpliedBoolOptionsNoFlagPresent) { 380 const char *Args[] = {""}; 381 382 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 383 384 ASSERT_FALSE(Diags->hasErrorOccurred()); 385 ASSERT_FALSE(Invocation.getLangOpts()->CLUnsafeMath); 386 ASSERT_FALSE(Invocation.getCodeGenOpts().LessPreciseFPMAD); 387 ASSERT_FALSE(Invocation.getLangOpts()->UnsafeFPMath); 388 ASSERT_FALSE(Invocation.getLangOpts()->AllowRecip); 389 390 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 391 392 // Not generated - missing. 393 ASSERT_THAT(GeneratedArgs, 394 Not(Contains(StrEq("-cl-unsafe-math-optimizations")))); 395 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable")))); 396 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-menable-unsafe-fp-math")))); 397 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math")))); 398 } 399 400 TEST_F(CommandLineTest, ImpliedBoolOptionsRootFlagPresent) { 401 const char *Args[] = {"-cl-unsafe-math-optimizations"}; 402 403 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 404 405 ASSERT_FALSE(Diags->hasErrorOccurred()); 406 // Explicitly provided root flag. 407 ASSERT_TRUE(Invocation.getLangOpts()->CLUnsafeMath); 408 // Directly implied by explicitly provided root flag. 409 ASSERT_TRUE(Invocation.getCodeGenOpts().LessPreciseFPMAD); 410 ASSERT_TRUE(Invocation.getLangOpts()->UnsafeFPMath); 411 // Transitively implied by explicitly provided root flag. 412 ASSERT_TRUE(Invocation.getLangOpts()->AllowRecip); 413 414 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 415 416 // Generated - explicitly provided. 417 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-unsafe-math-optimizations"))); 418 // Not generated - implied by the generated root flag. 419 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable")))); 420 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-menable-unsafe-fp-math")))); 421 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math")))); 422 } 423 424 TEST_F(CommandLineTest, ImpliedBoolOptionsAllFlagsPresent) { 425 const char *Args[] = {"-cl-unsafe-math-optimizations", "-cl-mad-enable", 426 "-menable-unsafe-fp-math", "-freciprocal-math"}; 427 428 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 429 430 ASSERT_FALSE(Diags->hasErrorOccurred()); 431 ASSERT_TRUE(Invocation.getLangOpts()->CLUnsafeMath); 432 ASSERT_TRUE(Invocation.getCodeGenOpts().LessPreciseFPMAD); 433 ASSERT_TRUE(Invocation.getLangOpts()->UnsafeFPMath); 434 ASSERT_TRUE(Invocation.getLangOpts()->AllowRecip); 435 436 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 437 438 // Generated - explicitly provided. 439 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-unsafe-math-optimizations"))); 440 // Not generated - implied by their generated parent. 441 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-cl-mad-enable")))); 442 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-menable-unsafe-fp-math")))); 443 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math")))); 444 } 445 446 TEST_F(CommandLineTest, ImpliedBoolOptionsImpliedFlagsPresent) { 447 const char *Args[] = {"-cl-mad-enable", "-menable-unsafe-fp-math", 448 "-freciprocal-math"}; 449 450 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 451 ASSERT_FALSE(Diags->hasErrorOccurred()); 452 ASSERT_FALSE(Invocation.getLangOpts()->CLUnsafeMath); 453 ASSERT_TRUE(Invocation.getCodeGenOpts().LessPreciseFPMAD); 454 ASSERT_TRUE(Invocation.getLangOpts()->UnsafeFPMath); 455 ASSERT_TRUE(Invocation.getLangOpts()->AllowRecip); 456 457 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 458 // Not generated - missing. 459 ASSERT_THAT(GeneratedArgs, 460 Not(Contains(StrEq("-cl-unsafe-math-optimizations")))); 461 // Generated - explicitly provided. 462 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-mad-enable"))); 463 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-menable-unsafe-fp-math"))); 464 // Not generated - implied by its generated parent. 465 ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-freciprocal-math")))); 466 } 467 468 TEST_F(CommandLineTest, PresentAndNotImpliedGenerated) { 469 const char *Args[] = {"-cl-mad-enable", "-menable-unsafe-fp-math"}; 470 471 CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags); 472 473 ASSERT_FALSE(Diags->hasErrorOccurred()); 474 475 Invocation.generateCC1CommandLine(GeneratedArgs, *this); 476 477 // Present options that were not implied are generated. 478 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-cl-mad-enable"))); 479 ASSERT_THAT(GeneratedArgs, Contains(StrEq("-menable-unsafe-fp-math"))); 480 } 481 } // anonymous namespace 482