r356508 - Add --unwindlib=[libgcc|compiler-rt] to parallel --rtlib= [take 2]

Sterling Augustine via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 19 13:02:00 PDT 2019


Author: saugustine
Date: Tue Mar 19 13:01:59 2019
New Revision: 356508

URL: http://llvm.org/viewvc/llvm-project?rev=356508&view=rev
Log:
Add --unwindlib=[libgcc|compiler-rt] to parallel --rtlib= [take 2]

"clang++ hello.cc --rtlib=compiler-rt"

now can works without specifying additional unwind or exception
handling libraries.

This reworked version of the feature no longer modifies today's default
unwind library for compiler-rt: which is nothing. Rather, a user
can specify -DCLANG_DEFAULT_UNWINDLIB=libunwind when configuring
the compiler.

This should address the issues from the previous version.

Update tests for new --unwindlib semantics.

Differential Revision: https://reviews.llvm.org/D59109

Added:
    cfe/trunk/test/Driver/compiler-rt-unwind.c
Modified:
    cfe/trunk/CMakeLists.txt
    cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
    cfe/trunk/include/clang/Config/config.h.cmake
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/include/clang/Driver/ToolChain.h
    cfe/trunk/lib/Driver/ToolChain.cpp
    cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp

Modified: cfe/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CMakeLists.txt?rev=356508&r1=356507&r2=356508&view=diff
==============================================================================
--- cfe/trunk/CMakeLists.txt (original)
+++ cfe/trunk/CMakeLists.txt Tue Mar 19 13:01:59 2019
@@ -266,6 +266,24 @@ if (NOT(CLANG_DEFAULT_RTLIB STREQUAL ""
     "Default runtime library to use (\"libgcc\" or \"compiler-rt\", empty for platform default)" FORCE)
 endif()
 
+set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
+  "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty to match runtime library.)")
+if (CLANG_DEFAULT_UNWINDLIB STREQUAL "")
+  if (CLANG_DEFAULT_RTLIB STREQUAL "libgcc")
+    set (CLANG_DEFAULT_UNWINDLIB "libgcc" CACHE STRING "" FORCE)
+  elseif (CLANG_DEFAULT_RTLIBS STREQUAL "libunwind")
+    set (CLANG_DEFAULT_UNWINDLIB "none" CACHE STRING "" FORCE)
+  endif()
+endif()
+
+if (NOT(CLANG_DEFAULT_UNWINDLIB STREQUAL "none" OR
+        CLANG_DEFAULT_UNWINDLIB STREQUAL "libgcc" OR
+        CLANG_DEFAULT_UNWINDLIB STREQUAL "libunwind"))
+  message(WARNING "Resetting default unwindlib to use platform default")
+  set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
+    "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty for none)" FORCE)
+endif()
+
 set(CLANG_DEFAULT_OBJCOPY "objcopy" CACHE STRING
   "Default objcopy executable to use.")
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=356508&r1=356507&r2=356508&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Tue Mar 19 13:01:59 2019
@@ -51,6 +51,10 @@ def err_drv_invalid_rtlib_name : Error<
   "invalid runtime library name in argument '%0'">;
 def err_drv_unsupported_rtlib_for_platform : Error<
   "unsupported runtime library '%0' for platform '%1'">;
+def err_drv_invalid_unwindlib_name : Error<
+  "invalid unwind library name in argument '%0'">;
+def err_drv_incompatible_unwindlib : Error<
+  "--rtlib=libgcc requires --unwindlib=libgcc">;
 def err_drv_invalid_stdlib_name : Error<
   "invalid library name in argument '%0'">;
 def err_drv_invalid_output_with_multiple_archs : Error<

Modified: cfe/trunk/include/clang/Config/config.h.cmake
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Config/config.h.cmake?rev=356508&r1=356507&r2=356508&view=diff
==============================================================================
--- cfe/trunk/include/clang/Config/config.h.cmake (original)
+++ cfe/trunk/include/clang/Config/config.h.cmake Tue Mar 19 13:01:59 2019
@@ -23,6 +23,9 @@
 /* Default runtime library to use. */
 #define CLANG_DEFAULT_RTLIB "${CLANG_DEFAULT_RTLIB}"
 
+/* Default unwind library to use. */
+#define CLANG_DEFAULT_UNWINDLIB "${CLANG_DEFAULT_UNWINDLIB}"
+
 /* Default objcopy to use */
 #define CLANG_DEFAULT_OBJCOPY "${CLANG_DEFAULT_OBJCOPY}"
 

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=356508&r1=356507&r2=356508&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Tue Mar 19 13:01:59 2019
@@ -2591,6 +2591,8 @@ def std_EQ : Joined<["-", "--"], "std=">
   }]>;
 def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
   HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">;
+def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">, Flags<[CC1Option]>,
+  HelpText<"Unwind library to use">, Values<"libgcc,unwindlib,platform">;
 def sub__library : JoinedOrSeparate<["-"], "sub_library">;
 def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
 def system_header_prefix : Joined<["--"], "system-header-prefix=">,

Modified: cfe/trunk/include/clang/Driver/ToolChain.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=356508&r1=356507&r2=356508&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/ToolChain.h (original)
+++ cfe/trunk/include/clang/Driver/ToolChain.h Tue Mar 19 13:01:59 2019
@@ -99,6 +99,12 @@ public:
     RLT_Libgcc
   };
 
+  enum UnwindLibType {
+    UNW_None,
+    UNW_CompilerRT,
+    UNW_Libgcc
+  };
+
   enum RTTIMode {
     RM_Enabled,
     RM_Disabled,
@@ -369,6 +375,10 @@ public:
     return ToolChain::CST_Libstdcxx;
   }
 
+  virtual UnwindLibType GetDefaultUnwindLibType() const {
+    return ToolChain::UNW_None;
+  }
+
   virtual std::string getCompilerRTPath() const;
 
   virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
@@ -513,6 +523,10 @@ public:
   // given compilation arguments.
   virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
 
+  // GetUnwindLibType - Determine the unwind library type to use with the
+  // given compilation arguments.
+  virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
+
   /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
   /// the include paths to use for the given C++ standard library type.
   virtual void

Modified: cfe/trunk/lib/Driver/ToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChain.cpp?rev=356508&r1=356507&r2=356508&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChain.cpp Tue Mar 19 13:01:59 2019
@@ -693,6 +693,33 @@ ToolChain::RuntimeLibType ToolChain::Get
   return GetDefaultRuntimeLibType();
 }
 
+ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
+    const ArgList &Args) const {
+  const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
+  StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
+
+  if (LibName == "none")
+    return ToolChain::UNW_None;
+  else if (LibName == "platform" || LibName == "") {
+    ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
+    if (RtLibType == ToolChain::RLT_CompilerRT)
+      return ToolChain::UNW_None;
+    else if (RtLibType == ToolChain::RLT_Libgcc)
+      return ToolChain::UNW_Libgcc;
+  } else if (LibName == "libunwind") {
+    if (GetRuntimeLibType(Args) == RLT_Libgcc)
+      getDriver().Diag(diag::err_drv_incompatible_unwindlib);
+    return ToolChain::UNW_CompilerRT;
+  } else if (LibName == "libgcc")
+    return ToolChain::UNW_Libgcc;
+
+  if (A)
+    getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
+        << A->getAsString(Args);
+
+  return GetDefaultUnwindLibType();
+}
+
 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
   const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
   StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;

Modified: cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp?rev=356508&r1=356507&r2=356508&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp Tue Mar 19 13:01:59 2019
@@ -1159,47 +1159,80 @@ bool tools::isObjCAutoRefCount(const Arg
   return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
 }
 
-static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
-                      ArgStringList &CmdArgs, const ArgList &Args) {
-  bool isAndroid = Triple.isAndroid();
-  bool isCygMing = Triple.isOSCygMing();
-  bool IsIAMCU = Triple.isOSIAMCU();
-  bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
-                      Args.hasArg(options::OPT_static) ||
-                      Args.hasArg(options::OPT_static_pie);
-
-  bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc);
-  bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc;
-
-  // Gcc adds libgcc arguments in various ways:
-  //
-  // gcc <none>:     -lgcc --as-needed -lgcc_s --no-as-needed
-  // g++ <none>:                       -lgcc_s               -lgcc
-  // gcc shared:                       -lgcc_s               -lgcc
-  // g++ shared:                       -lgcc_s               -lgcc
-  // gcc static:     -lgcc             -lgcc_eh
-  // g++ static:     -lgcc             -lgcc_eh
-  // gcc static-pie: -lgcc             -lgcc_eh
-  // g++ static-pie: -lgcc             -lgcc_eh
-  //
-  // Also, certain targets need additional adjustments.
+enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
 
-  bool LibGccFirst = (D.CCCIsCC() && UnspecifiedLibgcc) || StaticLibgcc;
-  if (LibGccFirst)
-    CmdArgs.push_back("-lgcc");
+static LibGccType getLibGccType(const ArgList &Args) {
+  bool Static = Args.hasArg(options::OPT_static_libgcc) ||
+                Args.hasArg(options::OPT_static) ||
+                Args.hasArg(options::OPT_static_pie);
+
+  bool Shared = Args.hasArg(options::OPT_shared_libgcc);
+  if (Shared)
+    return LibGccType::SharedLibGcc;
+  if (Static)
+    return LibGccType::StaticLibGcc;
+  return LibGccType::UnspecifiedLibGcc;
+}
 
-  bool AsNeeded = D.CCCIsCC() && UnspecifiedLibgcc && !isAndroid && !isCygMing;
+// Gcc adds libgcc arguments in various ways:
+//
+// gcc <none>:     -lgcc --as-needed -lgcc_s --no-as-needed
+// g++ <none>:                       -lgcc_s               -lgcc
+// gcc shared:                       -lgcc_s               -lgcc
+// g++ shared:                       -lgcc_s               -lgcc
+// gcc static:     -lgcc             -lgcc_eh
+// g++ static:     -lgcc             -lgcc_eh
+// gcc static-pie: -lgcc             -lgcc_eh
+// g++ static-pie: -lgcc             -lgcc_eh
+//
+// Also, certain targets need additional adjustments.
+
+static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
+                             ArgStringList &CmdArgs, const ArgList &Args) {
+  ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
+  // Targets that don't use unwind libraries.
+  if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() ||
+      TC.getTriple().isOSBinFormatWasm() ||
+      UNW == ToolChain::UNW_None)
+    return;
+
+  LibGccType LGT = getLibGccType(Args);
+  bool AsNeeded = D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc &&
+                  !TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing();
   if (AsNeeded)
     CmdArgs.push_back("--as-needed");
 
-  if ((UnspecifiedLibgcc || SharedLibgcc) && !isAndroid)
-    CmdArgs.push_back("-lgcc_s");
-
-  else if (StaticLibgcc && !isAndroid && !IsIAMCU)
-    CmdArgs.push_back("-lgcc_eh");
+  switch (UNW) {
+  case ToolChain::UNW_None:
+    return;
+  case ToolChain::UNW_Libgcc: {
+    LibGccType LGT = getLibGccType(Args);
+    if (LGT == LibGccType::UnspecifiedLibGcc || LGT == LibGccType::SharedLibGcc)
+      CmdArgs.push_back("-lgcc_s");
+    else if (LGT == LibGccType::StaticLibGcc)
+      CmdArgs.push_back("-lgcc_eh");
+    break;
+  }
+  case ToolChain::UNW_CompilerRT:
+    CmdArgs.push_back("-lunwind");
+    break;
+  }
 
   if (AsNeeded)
     CmdArgs.push_back("--no-as-needed");
+}
+
+static void AddLibgcc(const ToolChain &TC, const Driver &D,
+                      ArgStringList &CmdArgs, const ArgList &Args) {
+  bool isAndroid = TC.getTriple().isAndroid();
+
+  LibGccType LGT = getLibGccType(Args);
+  bool LibGccFirst = (D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc) ||
+                     LGT == LibGccType::StaticLibGcc;
+  if (LibGccFirst)
+    CmdArgs.push_back("-lgcc");
+
+  AddUnwindLibrary(TC, D, CmdArgs, Args);
 
   if (!LibGccFirst)
     CmdArgs.push_back("-lgcc");
@@ -1209,7 +1242,7 @@ static void AddLibgcc(const llvm::Triple
   //
   // NOTE: This fixes a link error on Android MIPS as well.  The non-static
   // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
-  if (isAndroid && !StaticLibgcc)
+  if (isAndroid && getLibGccType(Args) != LibGccType::StaticLibGcc)
     CmdArgs.push_back("-ldl");
 }
 
@@ -1221,6 +1254,7 @@ void tools::AddRunTimeLibs(const ToolCha
   switch (RLT) {
   case ToolChain::RLT_CompilerRT:
     CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
+    AddUnwindLibrary(TC, D, CmdArgs, Args);
     break;
   case ToolChain::RLT_Libgcc:
     // Make sure libgcc is not used under MSVC environment by default
@@ -1232,7 +1266,7 @@ void tools::AddRunTimeLibs(const ToolCha
             << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
       }
     } else
-      AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
+      AddLibgcc(TC, D, CmdArgs, Args);
     break;
   }
 }

Added: cfe/trunk/test/Driver/compiler-rt-unwind.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/compiler-rt-unwind.c?rev=356508&view=auto
==============================================================================
--- cfe/trunk/test/Driver/compiler-rt-unwind.c (added)
+++ cfe/trunk/test/Driver/compiler-rt-unwind.c Tue Mar 19 13:01:59 2019
@@ -0,0 +1,49 @@
+// General tests that the driver handles combinations of --rtlib=XXX and
+// --unwindlib=XXX properly.
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-EMPTY %s
+// RTLIB-EMPTY: "{{.*}}lgcc"
+// RTLIB-EMPTY: "{{.*}}-lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-GCC %s
+// RTLIB-GCC: "{{.*}}lgcc"
+// RTLIB-GCC: "{{.*}}lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s
+// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lgcc"
+// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lunwind"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1   \
+// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT %s
+// RTLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1   \
+// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC %s
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}libclang_rt.builtins-x86_64.a"
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1              \
+// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
+// RUN:     -static --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC %s
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}libclang_rt.builtins-x86_64.a"
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}lgcc_eh"
+//
+// RUN: not %clang -no-canonical-prefixes %s -o %t.o 2> %t.err              \
+// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
+// RUN:     --gcc-toolchain="" \
+// RUN: FileCheck --input-file=%t.err --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER_RT %s
+// RTLIB-GCC-UNWINDLIB-COMPILER_RT: "{{[.|\\\n]*}}--rtlib=libgcc requires --unwindlib=libgcc"




More information about the cfe-commits mailing list