brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.0 KiB · 277fa26 Raw
558 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// Unit tests for Multilib and MultilibSet10//11//===----------------------------------------------------------------------===//12 13#include "clang/Driver/Multilib.h"14#include "SimpleDiagnosticConsumer.h"15#include "clang/Basic/LLVM.h"16#include "clang/Basic/Version.h"17#include "clang/Driver/CommonArgs.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 24using namespace clang::driver;25using namespace clang;26 27TEST(MultilibTest, OpEqReflexivity1) {28  Multilib M;29  ASSERT_TRUE(M == M) << "Multilib::operator==() is not reflexive";30}31 32TEST(MultilibTest, OpEqReflexivity2) {33  ASSERT_TRUE(Multilib() == Multilib())34      << "Separately constructed default multilibs are not equal";35}36 37TEST(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 43TEST(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 51TEST(MultilibTest, OpEqInequivalence2) {52  Multilib M1;53  Multilib M2({}, {}, {}, {"+foo"});54  ASSERT_FALSE(M1 == M2) << "Flags make Multilibs different";55}56 57TEST(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 66TEST(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 75TEST(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 84TEST(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 92TEST(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 100TEST(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 108TEST(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 115TEST(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 128TEST(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 139TEST(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 152TEST(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 173TEST(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 195static void diagnosticCallback(const llvm::SMDiagnostic &D, void *Out) {196  *reinterpret_cast<std::string *>(Out) = D.getMessage();197}198 199static 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 209static 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.cpp218#define YAML_PREAMBLE "MultilibVersion: 1.0\n"219 220TEST(MultilibTest, ParseInvalid) {221  std::string Diagnostic;222 223  MultilibSet MS;224 225  EXPECT_FALSE(parseYaml(MS, Diagnostic, R"(226Variants: []227)"));228  EXPECT_TRUE(229      StringRef(Diagnostic).contains("missing required key 'MultilibVersion'"))230      << Diagnostic;231 232  // Reject files with a different major version233  EXPECT_FALSE(parseYaml(MS, Diagnostic,234                         R"(235MultilibVersion: 2.0236Variants: []237)"));238  EXPECT_TRUE(239      StringRef(Diagnostic).contains("multilib version 2.0 is unsupported"))240      << Diagnostic;241  EXPECT_FALSE(parseYaml(MS, Diagnostic,242                         R"(243MultilibVersion: 0.1244Variants: []245)"));246  EXPECT_TRUE(247      StringRef(Diagnostic).contains("multilib version 0.1 is unsupported"))248      << Diagnostic;249 250  // Reject files with a later minor version251  EXPECT_FALSE(parseYaml(MS, Diagnostic,252                         R"(253MultilibVersion: 1.9254Variants: []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 minor261  // version262  EXPECT_TRUE(parseYaml(MS, Diagnostic, R"(263MultilibVersion: 1.0264Variants: []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"(272Variants:273- Dir: /abc274  Flags: []275)"));276  EXPECT_TRUE(StringRef(Diagnostic).contains("paths must be relative"))277      << Diagnostic;278 279  EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"(280Variants: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"(289Variants: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"(296Variants: []297Mappings:298- Match: abc299)"));300  EXPECT_TRUE(StringRef(Diagnostic).contains("value required for 'Flags'"))301      << Diagnostic;302 303  EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"(304Variants: []305Mappings:306- Dir: .307  Match: '('308  Flags: []309)"));310  EXPECT_TRUE(StringRef(Diagnostic).contains("parentheses not balanced"))311      << Diagnostic;312}313 314TEST(MultilibTest, Parse) {315  MultilibSet MS;316  EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(317Variants: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"(325Variants:326- Dir: abc327  Flags: []328)"));329  EXPECT_EQ(1U, MS.size());330  EXPECT_EQ("/abc", MS.begin()->gccSuffix());331 332  EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(333Variants:334- Dir: pqr335  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"(343Variants:344- Dir: pqr345  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"(352Variants:353- Dir: a354  Flags: []355- Dir: b356  Flags: []357)"));358  EXPECT_EQ(2U, MS.size());359}360 361TEST(MultilibTest, SelectSoft) {362  MultilibSet MS;363  llvm::SmallVector<Multilib> Selected;364  ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(365Variants:366- Dir: s367  Flags: [-mfloat-abi=soft]368Mappings:369- Match: -mfloat-abi=softfp370  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 378TEST(MultilibTest, SelectSoftFP) {379  MultilibSet MS;380  llvm::SmallVector<Multilib> Selected;381  ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(382Variants:383- Dir: f384  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 392TEST(MultilibTest, SelectHard) {393  // If hard float is all that's available then select that only if compiling394  // with hard float.395  MultilibSet MS;396  llvm::SmallVector<Multilib> Selected;397  ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(398Variants:399- Dir: h400  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 408TEST(MultilibTest, SelectFloatABI) {409  MultilibSet MS;410  llvm::SmallVector<Multilib> Selected;411  ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(412Variants:413- Dir: s414  Flags: [-mfloat-abi=soft]415- Dir: f416  Flags: [-mfloat-abi=softfp]417- Dir: h418  Flags: [-mfloat-abi=hard]419Mappings:420- Match: -mfloat-abi=softfp421  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 432TEST(MultilibTest, SelectFloatABIReversed) {433  // If soft is specified after softfp then softfp will never be434  // 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"(438Variants:439- Dir: h440  Flags: [-mfloat-abi=hard]441- Dir: f442  Flags: [-mfloat-abi=softfp]443- Dir: s444  Flags: [-mfloat-abi=soft]445Mappings:446- Match: -mfloat-abi=softfp447  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 458TEST(MultilibTest, SelectMClass) {459  Driver TheDriver = diagnostic_test_driver();460 461  const char *MultilibSpec = YAML_PREAMBLE R"(462Variants:463- Dir: thumb/v6-m/nofp464  Flags: [--target=thumbv6m-none-unknown-eabi, -mfpu=none]465 466- Dir: thumb/v7-m/nofp467  Flags: [--target=thumbv7m-none-unknown-eabi, -mfpu=none]468 469- Dir: thumb/v7e-m/nofp470  Flags: [--target=thumbv7em-none-unknown-eabi, -mfpu=none]471 472- Dir: thumb/v8-m.main/nofp473  Flags: [--target=thumbv8m.main-none-unknown-eabi, -mfpu=none]474 475- Dir: thumb/v8.1-m.main/nofp/nomve476  Flags: [--target=thumbv8.1m.main-none-unknown-eabi, -mfpu=none]477 478- Dir: thumb/v7e-m/fpv4_sp_d16479  Flags: [--target=thumbv7em-none-unknown-eabihf, -mfpu=fpv4-sp-d16]480 481- Dir: thumb/v7e-m/fpv5_d16482  Flags: [--target=thumbv7em-none-unknown-eabihf, -mfpu=fpv5-d16]483 484- Dir: thumb/v8-m.main/fp485  Flags: [--target=thumbv8m.main-none-unknown-eabihf]486 487- Dir: thumb/v8.1-m.main/fp488  Flags: [--target=thumbv8.1m.main-none-unknown-eabihf]489 490- Dir: thumb/v8.1-m.main/nofp/mve491  Flags: [--target=thumbv8.1m.main-none-unknown-eabihf, -march=thumbv8.1m.main+mve]492 493Mappings:494- Match: --target=thumbv8(\.[0-9]+)?m\.base-none-unknown-eabi495  Flags: [--target=thumbv6m-none-unknown-eabi]496- Match: -target=thumbv8\.[1-9]m\.main-none-unknown-eabi497  Flags: [--target=thumbv8.1m.main-none-unknown-eabi]498- Match: -target=thumbv8\.[1-9]m\.main-none-unknown-eabihf499  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