michaelplatings created this revision.
michaelplatings added a reviewer: phosek.
Herald added a subscriber: abrachet.
Herald added a project: All.
michaelplatings requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

The plan is to change how multilib works under the hood and this test gives 
confidence that the changes won't break user-visible behaviour.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142878

Files:
  clang/lib/Driver/ToolChains/Fuchsia.cpp
  clang/lib/Driver/ToolChains/Fuchsia.h
  clang/unittests/Driver/CMakeLists.txt
  clang/unittests/Driver/FuchsiaTest.cpp

Index: clang/unittests/Driver/FuchsiaTest.cpp
===================================================================
--- /dev/null
+++ clang/unittests/Driver/FuchsiaTest.cpp
@@ -0,0 +1,80 @@
+//===- unittests/Driver/FuchsiaTest.cpp --- Fuchsia tests ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Unit tests for Fuchsia
+//
+//===----------------------------------------------------------------------===//
+
+#include "../../lib/Driver/ToolChains/Fuchsia.h"
+#include "gtest/gtest.h"
+
+using namespace clang::driver;
+
+/*
+This test was added prior to changing the behaviour of Multilib.
+The way that Fuchsia used Multilib made it very likely that the change
+would cause it to break so by adding this exhaustive test we avoid that
+possibility.
+*/
+TEST(FuchsiaTest, MultilibVariant) {
+  MultilibSet Multilibs;
+  toolchains::Fuchsia::configureMultilibs(Multilibs);
+
+  std::string Actual;
+
+  for (bool Itanium : {false, true}) {
+    for (bool RelativeVtables : {false, true}) {
+      for (bool Hwasan : {false, true}) {
+        for (bool Asan : {false, true}) {
+          for (bool Exceptions : {false, true}) {
+            Multilib::flags_list Flags;
+            toolchains::Fuchsia::configureMultilibFlags(
+                Flags, Exceptions, Asan, Hwasan, RelativeVtables, Itanium);
+            Multilib Selected;
+            EXPECT_TRUE(Multilibs.select(Flags, Selected));
+            Actual += Selected.gccSuffix() + "\n";
+          }
+        }
+      }
+    }
+  }
+  std::string Expected = R"(/noexcept
+
+/asan+noexcept
+/asan
+/hwasan+noexcept
+/hwasan
+/hwasan+noexcept
+/hwasan
+/relative-vtables+noexcept
+/relative-vtables
+/relative-vtables+asan+noexcept
+/relative-vtables+asan
+/relative-vtables+hwasan+noexcept
+/relative-vtables+hwasan
+/relative-vtables+hwasan+noexcept
+/relative-vtables+hwasan
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+/compat
+)";
+  EXPECT_EQ(Expected, Actual);
+}
Index: clang/unittests/Driver/CMakeLists.txt
===================================================================
--- clang/unittests/Driver/CMakeLists.txt
+++ clang/unittests/Driver/CMakeLists.txt
@@ -9,6 +9,7 @@
 add_clang_unittest(ClangDriverTests
   DistroTest.cpp
   DXCModeTest.cpp
+  FuchsiaTest.cpp
   ToolChainTest.cpp
   ModuleCacheTest.cpp
   MultilibTest.cpp
Index: clang/lib/Driver/ToolChains/Fuchsia.h
===================================================================
--- clang/lib/Driver/ToolChains/Fuchsia.h
+++ clang/lib/Driver/ToolChains/Fuchsia.h
@@ -98,6 +98,11 @@
 
   const char *getDefaultLinker() const override { return "ld.lld"; }
 
+  static void configureMultilibs(MultilibSet &);
+  static void configureMultilibFlags(Multilib::flags_list &, bool Exceptions,
+                                     bool Asan, bool Hwasan,
+                                     bool RelativeVtables, bool Itanium);
+
 protected:
   Tool *buildLinker() const override;
 };
Index: clang/lib/Driver/ToolChains/Fuchsia.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -215,6 +215,35 @@
     return FP;
   };
 
+  configureMultilibs(Multilibs);
+
+  Multilibs.FilterOut([&](const Multilib &M) {
+    std::vector<std::string> RD = FilePaths(M);
+    return llvm::all_of(RD, [&](std::string P) { return !getVFS().exists(P); });
+  });
+
+  Multilib::flags_list Flags;
+  configureMultilibFlags(
+      Flags,
+      Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
+      getSanitizerArgs(Args).needsAsanRt(),
+      getSanitizerArgs(Args).needsHwasanRt(),
+      Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
+                   options::OPT_fno_experimental_relative_cxx_abi_vtables,
+                   false),
+      Args.getLastArgValue(options::OPT_fcxx_abi_EQ) == "itanium");
+
+  Multilibs.setFilePathsCallback(FilePaths);
+
+  if (Multilibs.select(Flags, SelectedMultilib))
+    if (!SelectedMultilib.isDefault())
+      if (const auto &PathsCallback = Multilibs.filePathsCallback())
+        for (const auto &Path : PathsCallback(SelectedMultilib))
+          // Prepend the multilib path to ensure it takes the precedence.
+          getFilePaths().insert(getFilePaths().begin(), Path);
+}
+
+void Fuchsia::configureMultilibs(MultilibSet &Multilibs) {
   Multilibs.push_back(Multilib());
   // Use the noexcept variant with -fno-exceptions to avoid the extra overhead.
   Multilibs.push_back(Multilib("noexcept", {}, {}, 1)
@@ -264,37 +293,18 @@
                           .flag("+fno-exceptions"));
   // Use Itanium C++ ABI for the compat multilib.
   Multilibs.push_back(Multilib("compat", {}, {}, 12).flag("+fc++-abi=itanium"));
+}
 
-  Multilibs.FilterOut([&](const Multilib &M) {
-    std::vector<std::string> RD = FilePaths(M);
-    return llvm::all_of(RD, [&](std::string P) { return !getVFS().exists(P); });
-  });
-
-  Multilib::flags_list Flags;
-  addMultilibFlag(
-      Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
-      "fexceptions", Flags);
-  addMultilibFlag(getSanitizerArgs(Args).needsAsanRt(), "fsanitize=address",
-                  Flags);
-  addMultilibFlag(getSanitizerArgs(Args).needsHwasanRt(), "fsanitize=hwaddress",
+void Fuchsia::configureMultilibFlags(Multilib::flags_list &Flags,
+                                     bool Exceptions, bool Asan, bool Hwasan,
+                                     bool RelativeVtables, bool Itanium) {
+  addMultilibFlag(Exceptions, "fexceptions", Flags);
+  addMultilibFlag(!Exceptions, "fno-exceptions", Flags);
+  addMultilibFlag(Asan, "fsanitize=address", Flags);
+  addMultilibFlag(Hwasan, "fsanitize=hwaddress", Flags);
+  addMultilibFlag(RelativeVtables, "fexperimental-relative-c++-abi-vtables",
                   Flags);
-
-  addMultilibFlag(
-      Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
-                   options::OPT_fno_experimental_relative_cxx_abi_vtables,
-                   /*default=*/false),
-      "fexperimental-relative-c++-abi-vtables", Flags);
-  addMultilibFlag(Args.getLastArgValue(options::OPT_fcxx_abi_EQ) == "itanium",
-                  "fc++-abi=itanium", Flags);
-
-  Multilibs.setFilePathsCallback(FilePaths);
-
-  if (Multilibs.select(Flags, SelectedMultilib))
-    if (!SelectedMultilib.isDefault())
-      if (const auto &PathsCallback = Multilibs.filePathsCallback())
-        for (const auto &Path : PathsCallback(SelectedMultilib))
-          // Prepend the multilib path to ensure it takes the precedence.
-          getFilePaths().insert(getFilePaths().begin(), Path);
+  addMultilibFlag(Itanium, "fc++-abi=itanium", Flags);
 }
 
 std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to