1 //===- unittests/Driver/MultilibTest.cpp --- Multilib 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 // Unit tests for Multilib and MultilibSet 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Driver/Multilib.h" 14 #include "../../lib/Driver/ToolChains/CommonArgs.h" 15 #include "SimpleDiagnosticConsumer.h" 16 #include "clang/Basic/LLVM.h" 17 #include "clang/Basic/Version.h" 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/StringSwitch.h" 21 #include "llvm/Support/SourceMgr.h" 22 #include "gtest/gtest.h" 23 24 using namespace clang::driver; 25 using namespace clang; 26 27 TEST(MultilibTest, OpEqReflexivity1) { 28 Multilib M; 29 ASSERT_TRUE(M == M) << "Multilib::operator==() is not reflexive"; 30 } 31 32 TEST(MultilibTest, OpEqReflexivity2) { 33 ASSERT_TRUE(Multilib() == Multilib()) 34 << "Separately constructed default multilibs are not equal"; 35 } 36 37 TEST(MultilibTest, OpEqReflexivity3) { 38 Multilib M1({}, {}, {}, {"+foo"}); 39 Multilib M2({}, {}, {}, {"+foo"}); 40 ASSERT_TRUE(M1 == M2) << "Multilibs with the same flag should be the same"; 41 } 42 43 TEST(MultilibTest, OpEqInequivalence1) { 44 Multilib M1({}, {}, {}, {"+foo"}); 45 Multilib M2({}, {}, {}, {"-foo"}); 46 ASSERT_FALSE(M1 == M2) << "Multilibs with conflicting flags are not the same"; 47 ASSERT_FALSE(M2 == M1) 48 << "Multilibs with conflicting flags are not the same (commuted)"; 49 } 50 51 TEST(MultilibTest, OpEqInequivalence2) { 52 Multilib M1; 53 Multilib M2({}, {}, {}, {"+foo"}); 54 ASSERT_FALSE(M1 == M2) << "Flags make Multilibs different"; 55 } 56 57 TEST(MultilibTest, OpEqEquivalence2) { 58 Multilib M1("/64"); 59 Multilib M2("/64"); 60 ASSERT_TRUE(M1 == M2) 61 << "Constructor argument must match Multilib::gccSuffix()"; 62 ASSERT_TRUE(M2 == M1) 63 << "Constructor argument must match Multilib::gccSuffix() (commuted)"; 64 } 65 66 TEST(MultilibTest, OpEqEquivalence3) { 67 Multilib M1("", "/32"); 68 Multilib M2("", "/32"); 69 ASSERT_TRUE(M1 == M2) 70 << "Constructor argument must match Multilib::osSuffix()"; 71 ASSERT_TRUE(M2 == M1) 72 << "Constructor argument must match Multilib::osSuffix() (commuted)"; 73 } 74 75 TEST(MultilibTest, OpEqEquivalence4) { 76 Multilib M1("", "", "/16"); 77 Multilib M2("", "", "/16"); 78 ASSERT_TRUE(M1 == M2) 79 << "Constructor argument must match Multilib::includeSuffix()"; 80 ASSERT_TRUE(M2 == M1) 81 << "Constructor argument must match Multilib::includeSuffix() (commuted)"; 82 } 83 84 TEST(MultilibTest, OpEqInequivalence3) { 85 Multilib M1("/foo"); 86 Multilib M2("/bar"); 87 ASSERT_FALSE(M1 == M2) << "Differing gccSuffixes should be different"; 88 ASSERT_FALSE(M2 == M1) 89 << "Differing gccSuffixes should be different (commuted)"; 90 } 91 92 TEST(MultilibTest, OpEqInequivalence4) { 93 Multilib M1("", "/foo"); 94 Multilib M2("", "/bar"); 95 ASSERT_FALSE(M1 == M2) << "Differing osSuffixes should be different"; 96 ASSERT_FALSE(M2 == M1) 97 << "Differing osSuffixes should be different (commuted)"; 98 } 99 100 TEST(MultilibTest, OpEqInequivalence5) { 101 Multilib M1("", "", "/foo"); 102 Multilib M2("", "", "/bar"); 103 ASSERT_FALSE(M1 == M2) << "Differing includeSuffixes should be different"; 104 ASSERT_FALSE(M2 == M1) 105 << "Differing includeSuffixes should be different (commuted)"; 106 } 107 108 TEST(MultilibTest, Construction1) { 109 Multilib M("/gcc64", "/os64", "/inc64"); 110 ASSERT_TRUE(M.gccSuffix() == "/gcc64"); 111 ASSERT_TRUE(M.osSuffix() == "/os64"); 112 ASSERT_TRUE(M.includeSuffix() == "/inc64"); 113 } 114 115 TEST(MultilibTest, Construction2) { 116 Multilib M1; 117 Multilib M2(""); 118 Multilib M3("", ""); 119 Multilib M4("", "", ""); 120 ASSERT_TRUE(M1 == M2) 121 << "Default arguments to Multilib constructor broken (first argument)"; 122 ASSERT_TRUE(M1 == M3) 123 << "Default arguments to Multilib constructor broken (second argument)"; 124 ASSERT_TRUE(M1 == M4) 125 << "Default arguments to Multilib constructor broken (third argument)"; 126 } 127 128 TEST(MultilibTest, Construction3) { 129 Multilib M({}, {}, {}, {"+f1", "+f2", "-f3"}); 130 for (Multilib::flags_list::const_iterator I = M.flags().begin(), 131 E = M.flags().end(); 132 I != E; ++I) { 133 ASSERT_TRUE(llvm::StringSwitch<bool>(*I) 134 .Cases("+f1", "+f2", "-f3", true) 135 .Default(false)); 136 } 137 } 138 139 TEST(MultilibTest, SetPushback) { 140 MultilibSet MS({ 141 Multilib("/one"), 142 Multilib("/two"), 143 }); 144 ASSERT_TRUE(MS.size() == 2); 145 for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) { 146 ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix()) 147 .Cases("/one", "/two", true) 148 .Default(false)); 149 } 150 } 151 152 TEST(MultilibTest, SetPriority) { 153 MultilibSet MS({ 154 Multilib("/foo", {}, {}, {"+foo"}), 155 Multilib("/bar", {}, {}, {"+bar"}), 156 }); 157 Driver TheDriver = diagnostic_test_driver(); 158 Multilib::flags_list Flags1 = {"+foo", "-bar"}; 159 llvm::SmallVector<Multilib> Selection1; 160 ASSERT_TRUE(MS.select(TheDriver, Flags1, Selection1)) 161 << "Flag set was {\"+foo\"}, but selection not found"; 162 ASSERT_TRUE(Selection1.back().gccSuffix() == "/foo") 163 << "Selection picked " << Selection1.back() << " which was not expected"; 164 165 Multilib::flags_list Flags2 = {"+foo", "+bar"}; 166 llvm::SmallVector<Multilib> Selection2; 167 ASSERT_TRUE(MS.select(TheDriver, Flags2, Selection2)) 168 << "Flag set was {\"+bar\"}, but selection not found"; 169 ASSERT_TRUE(Selection2.back().gccSuffix() == "/bar") 170 << "Selection picked " << Selection2.back() << " which was not expected"; 171 } 172 173 TEST(MultilibTest, SelectMultiple) { 174 MultilibSet MS({ 175 Multilib("/a", {}, {}, {"x"}), 176 Multilib("/b", {}, {}, {"y"}), 177 }); 178 llvm::SmallVector<Multilib> Selection; 179 Driver TheDriver = diagnostic_test_driver(); 180 181 ASSERT_TRUE(MS.select(TheDriver, {"x"}, Selection)); 182 ASSERT_EQ(1u, Selection.size()); 183 EXPECT_EQ("/a", Selection[0].gccSuffix()); 184 185 ASSERT_TRUE(MS.select(TheDriver, {"y"}, Selection)); 186 ASSERT_EQ(1u, Selection.size()); 187 EXPECT_EQ("/b", Selection[0].gccSuffix()); 188 189 ASSERT_TRUE(MS.select(TheDriver, {"y", "x"}, Selection)); 190 ASSERT_EQ(2u, Selection.size()); 191 EXPECT_EQ("/a", Selection[0].gccSuffix()); 192 EXPECT_EQ("/b", Selection[1].gccSuffix()); 193 } 194 195 static void diagnosticCallback(const llvm::SMDiagnostic &D, void *Out) { 196 *reinterpret_cast<std::string *>(Out) = D.getMessage(); 197 } 198 199 static bool parseYaml(MultilibSet &MS, std::string &Diagnostic, 200 const char *Data) { 201 auto ErrorOrMS = MultilibSet::parseYaml(llvm::MemoryBufferRef(Data, "TEST"), 202 diagnosticCallback, &Diagnostic); 203 if (ErrorOrMS.getError()) 204 return false; 205 MS = std::move(ErrorOrMS.get()); 206 return true; 207 } 208 209 static bool parseYaml(MultilibSet &MS, const char *Data) { 210 auto ErrorOrMS = MultilibSet::parseYaml(llvm::MemoryBufferRef(Data, "TEST")); 211 if (ErrorOrMS.getError()) 212 return false; 213 MS = std::move(ErrorOrMS.get()); 214 return true; 215 } 216 217 // When updating this version also update MultilibVersionCurrent in Multilib.cpp 218 #define YAML_PREAMBLE "MultilibVersion: 1.0\n" 219 220 TEST(MultilibTest, ParseInvalid) { 221 std::string Diagnostic; 222 223 MultilibSet MS; 224 225 EXPECT_FALSE(parseYaml(MS, Diagnostic, R"( 226 Variants: [] 227 )")); 228 EXPECT_TRUE( 229 StringRef(Diagnostic).contains("missing required key 'MultilibVersion'")) 230 << Diagnostic; 231 232 // Reject files with a different major version 233 EXPECT_FALSE(parseYaml(MS, Diagnostic, 234 R"( 235 MultilibVersion: 2.0 236 Variants: [] 237 )")); 238 EXPECT_TRUE( 239 StringRef(Diagnostic).contains("multilib version 2.0 is unsupported")) 240 << Diagnostic; 241 EXPECT_FALSE(parseYaml(MS, Diagnostic, 242 R"( 243 MultilibVersion: 0.1 244 Variants: [] 245 )")); 246 EXPECT_TRUE( 247 StringRef(Diagnostic).contains("multilib version 0.1 is unsupported")) 248 << Diagnostic; 249 250 // Reject files with a later minor version 251 EXPECT_FALSE(parseYaml(MS, Diagnostic, 252 R"( 253 MultilibVersion: 1.9 254 Variants: [] 255 )")); 256 EXPECT_TRUE( 257 StringRef(Diagnostic).contains("multilib version 1.9 is unsupported")) 258 << Diagnostic; 259 260 // Accept files with the same major version and the same or earlier minor 261 // version 262 EXPECT_TRUE(parseYaml(MS, Diagnostic, R"( 263 MultilibVersion: 1.0 264 Variants: [] 265 )")) << Diagnostic; 266 267 EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE)); 268 EXPECT_TRUE(StringRef(Diagnostic).contains("missing required key 'Variants'")) 269 << Diagnostic; 270 271 EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( 272 Variants: 273 - Dir: /abc 274 Flags: [] 275 )")); 276 EXPECT_TRUE(StringRef(Diagnostic).contains("paths must be relative")) 277 << Diagnostic; 278 279 EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( 280 Variants: 281 - Flags: [] 282 )")); 283 EXPECT_TRUE( 284 StringRef(Diagnostic) 285 .contains("one of the 'Dir' and 'Error' keys must be specified")) 286 << Diagnostic; 287 288 EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( 289 Variants: 290 - Dir: . 291 )")); 292 EXPECT_TRUE(StringRef(Diagnostic).contains("missing required key 'Flags'")) 293 << Diagnostic; 294 295 EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( 296 Variants: [] 297 Mappings: 298 - Match: abc 299 )")); 300 EXPECT_TRUE(StringRef(Diagnostic).contains("value required for 'Flags'")) 301 << Diagnostic; 302 303 EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( 304 Variants: [] 305 Mappings: 306 - Dir: . 307 Match: '(' 308 Flags: [] 309 )")); 310 EXPECT_TRUE(StringRef(Diagnostic).contains("parentheses not balanced")) 311 << Diagnostic; 312 } 313 314 TEST(MultilibTest, Parse) { 315 MultilibSet MS; 316 EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 317 Variants: 318 - Dir: . 319 Flags: [] 320 )")); 321 EXPECT_EQ(1U, MS.size()); 322 EXPECT_EQ("", MS.begin()->gccSuffix()); 323 324 EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 325 Variants: 326 - Dir: abc 327 Flags: [] 328 )")); 329 EXPECT_EQ(1U, MS.size()); 330 EXPECT_EQ("/abc", MS.begin()->gccSuffix()); 331 332 EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 333 Variants: 334 - Dir: pqr 335 Flags: [-mfloat-abi=soft] 336 )")); 337 EXPECT_EQ(1U, MS.size()); 338 EXPECT_EQ("/pqr", MS.begin()->gccSuffix()); 339 EXPECT_EQ(std::vector<std::string>({"-mfloat-abi=soft"}), 340 MS.begin()->flags()); 341 342 EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 343 Variants: 344 - Dir: pqr 345 Flags: [-mfloat-abi=soft, -fno-exceptions] 346 )")); 347 EXPECT_EQ(1U, MS.size()); 348 EXPECT_EQ(std::vector<std::string>({"-mfloat-abi=soft", "-fno-exceptions"}), 349 MS.begin()->flags()); 350 351 EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 352 Variants: 353 - Dir: a 354 Flags: [] 355 - Dir: b 356 Flags: [] 357 )")); 358 EXPECT_EQ(2U, MS.size()); 359 } 360 361 TEST(MultilibTest, SelectSoft) { 362 MultilibSet MS; 363 llvm::SmallVector<Multilib> Selected; 364 ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 365 Variants: 366 - Dir: s 367 Flags: [-mfloat-abi=soft] 368 Mappings: 369 - Match: -mfloat-abi=softfp 370 Flags: [-mfloat-abi=soft] 371 )")); 372 Driver TheDriver = diagnostic_test_driver(); 373 EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected)); 374 EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected)); 375 EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected)); 376 } 377 378 TEST(MultilibTest, SelectSoftFP) { 379 MultilibSet MS; 380 llvm::SmallVector<Multilib> Selected; 381 ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 382 Variants: 383 - Dir: f 384 Flags: [-mfloat-abi=softfp] 385 )")); 386 Driver TheDriver = diagnostic_test_driver(); 387 EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected)); 388 EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected)); 389 EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected)); 390 } 391 392 TEST(MultilibTest, SelectHard) { 393 // If hard float is all that's available then select that only if compiling 394 // with hard float. 395 MultilibSet MS; 396 llvm::SmallVector<Multilib> Selected; 397 ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 398 Variants: 399 - Dir: h 400 Flags: [-mfloat-abi=hard] 401 )")); 402 Driver TheDriver = diagnostic_test_driver(); 403 EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected)); 404 EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected)); 405 EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected)); 406 } 407 408 TEST(MultilibTest, SelectFloatABI) { 409 MultilibSet MS; 410 llvm::SmallVector<Multilib> Selected; 411 ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 412 Variants: 413 - Dir: s 414 Flags: [-mfloat-abi=soft] 415 - Dir: f 416 Flags: [-mfloat-abi=softfp] 417 - Dir: h 418 Flags: [-mfloat-abi=hard] 419 Mappings: 420 - Match: -mfloat-abi=softfp 421 Flags: [-mfloat-abi=soft] 422 )")); 423 Driver TheDriver = diagnostic_test_driver(); 424 MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected); 425 EXPECT_EQ("/s", Selected.back().gccSuffix()); 426 MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected); 427 EXPECT_EQ("/f", Selected.back().gccSuffix()); 428 MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected); 429 EXPECT_EQ("/h", Selected.back().gccSuffix()); 430 } 431 432 TEST(MultilibTest, SelectFloatABIReversed) { 433 // If soft is specified after softfp then softfp will never be 434 // selected because soft is compatible with softfp and last wins. 435 MultilibSet MS; 436 llvm::SmallVector<Multilib> Selected; 437 ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( 438 Variants: 439 - Dir: h 440 Flags: [-mfloat-abi=hard] 441 - Dir: f 442 Flags: [-mfloat-abi=softfp] 443 - Dir: s 444 Flags: [-mfloat-abi=soft] 445 Mappings: 446 - Match: -mfloat-abi=softfp 447 Flags: [-mfloat-abi=soft] 448 )")); 449 Driver TheDriver = diagnostic_test_driver(); 450 MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected); 451 EXPECT_EQ("/s", Selected.back().gccSuffix()); 452 MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected); 453 EXPECT_EQ("/s", Selected.back().gccSuffix()); 454 MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected); 455 EXPECT_EQ("/h", Selected.back().gccSuffix()); 456 } 457 458 TEST(MultilibTest, SelectMClass) { 459 Driver TheDriver = diagnostic_test_driver(); 460 461 const char *MultilibSpec = YAML_PREAMBLE R"( 462 Variants: 463 - Dir: thumb/v6-m/nofp 464 Flags: [--target=thumbv6m-none-unknown-eabi, -mfpu=none] 465 466 - Dir: thumb/v7-m/nofp 467 Flags: [--target=thumbv7m-none-unknown-eabi, -mfpu=none] 468 469 - Dir: thumb/v7e-m/nofp 470 Flags: [--target=thumbv7em-none-unknown-eabi, -mfpu=none] 471 472 - Dir: thumb/v8-m.main/nofp 473 Flags: [--target=thumbv8m.main-none-unknown-eabi, -mfpu=none] 474 475 - Dir: thumb/v8.1-m.main/nofp/nomve 476 Flags: [--target=thumbv8.1m.main-none-unknown-eabi, -mfpu=none] 477 478 - Dir: thumb/v7e-m/fpv4_sp_d16 479 Flags: [--target=thumbv7em-none-unknown-eabihf, -mfpu=fpv4-sp-d16] 480 481 - Dir: thumb/v7e-m/fpv5_d16 482 Flags: [--target=thumbv7em-none-unknown-eabihf, -mfpu=fpv5-d16] 483 484 - Dir: thumb/v8-m.main/fp 485 Flags: [--target=thumbv8m.main-none-unknown-eabihf] 486 487 - Dir: thumb/v8.1-m.main/fp 488 Flags: [--target=thumbv8.1m.main-none-unknown-eabihf] 489 490 - Dir: thumb/v8.1-m.main/nofp/mve 491 Flags: [--target=thumbv8.1m.main-none-unknown-eabihf, -march=thumbv8.1m.main+mve] 492 493 Mappings: 494 - Match: --target=thumbv8(\.[0-9]+)?m\.base-none-unknown-eabi 495 Flags: [--target=thumbv6m-none-unknown-eabi] 496 - Match: -target=thumbv8\.[1-9]m\.main-none-unknown-eabi 497 Flags: [--target=thumbv8.1m.main-none-unknown-eabi] 498 - Match: -target=thumbv8\.[1-9]m\.main-none-unknown-eabihf 499 Flags: [--target=thumbv8.1m.main-none-unknown-eabihf] 500 - Match: -march=thumbv8\.[1-9]m\.main.*\+mve($|\+).* 501 Flags: [-march=thumbv8.1m.main+mve] 502 )"; 503 504 MultilibSet MS; 505 llvm::SmallVector<Multilib> Selected; 506 ASSERT_TRUE(parseYaml(MS, MultilibSpec)); 507 508 ASSERT_TRUE(MS.select(TheDriver, 509 {"--target=thumbv6m-none-unknown-eabi", "-mfpu=none"}, 510 Selected)); 511 EXPECT_EQ("/thumb/v6-m/nofp", Selected.back().gccSuffix()); 512 513 ASSERT_TRUE(MS.select(TheDriver, 514 {"--target=thumbv7m-none-unknown-eabi", "-mfpu=none"}, 515 Selected)); 516 EXPECT_EQ("/thumb/v7-m/nofp", Selected.back().gccSuffix()); 517 518 ASSERT_TRUE(MS.select(TheDriver, 519 {"--target=thumbv7em-none-unknown-eabi", "-mfpu=none"}, 520 Selected)); 521 EXPECT_EQ("/thumb/v7e-m/nofp", Selected.back().gccSuffix()); 522 523 ASSERT_TRUE(MS.select( 524 TheDriver, {"--target=thumbv8m.main-none-unknown-eabi", "-mfpu=none"}, 525 Selected)); 526 EXPECT_EQ("/thumb/v8-m.main/nofp", Selected.back().gccSuffix()); 527 528 ASSERT_TRUE(MS.select( 529 TheDriver, {"--target=thumbv8.1m.main-none-unknown-eabi", "-mfpu=none"}, 530 Selected)); 531 EXPECT_EQ("/thumb/v8.1-m.main/nofp/nomve", Selected.back().gccSuffix()); 532 533 ASSERT_TRUE( 534 MS.select(TheDriver, 535 {"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv4-sp-d16"}, 536 Selected)); 537 EXPECT_EQ("/thumb/v7e-m/fpv4_sp_d16", Selected.back().gccSuffix()); 538 539 ASSERT_TRUE(MS.select( 540 TheDriver, {"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv5-d16"}, 541 Selected)); 542 EXPECT_EQ("/thumb/v7e-m/fpv5_d16", Selected.back().gccSuffix()); 543 544 ASSERT_TRUE(MS.select( 545 TheDriver, {"--target=thumbv8m.main-none-unknown-eabihf"}, Selected)); 546 EXPECT_EQ("/thumb/v8-m.main/fp", Selected.back().gccSuffix()); 547 548 ASSERT_TRUE(MS.select( 549 TheDriver, {"--target=thumbv8.1m.main-none-unknown-eabihf"}, Selected)); 550 EXPECT_EQ("/thumb/v8.1-m.main/fp", Selected.back().gccSuffix()); 551 552 ASSERT_TRUE(MS.select(TheDriver, 553 {"--target=thumbv8.1m.main-none-unknown-eabihf", 554 "-mfpu=none", "-march=thumbv8.1m.main+dsp+mve"}, 555 Selected)); 556 EXPECT_EQ("/thumb/v8.1-m.main/nofp/mve", Selected.back().gccSuffix()); 557 } 558