mgorny updated this revision to Diff 85875.
mgorny retitled this revision from "[Driver] Pass -lunwind when using libc++ + 
compiler-rt on Linux" to "[Driver] Pass -lunwind along with compiler-rt when 
necessary on Linux".
mgorny edited the summary of this revision.
mgorny added a comment.
Herald added subscribers: srhines, danalbert.

Here's a v2. It turns out that you also need `-lunwind` when using to link C 
programs with `-static -rtlib=compiler-rt`. I've also disabled the changes for 
Android targets.


https://reviews.llvm.org/D25402

Files:
  lib/Driver/Tools.cpp
  test/Driver/linux-ld.c


Index: test/Driver/linux-ld.c
===================================================================
--- test/Driver/linux-ld.c
+++ test/Driver/linux-ld.c
@@ -443,6 +443,34 @@
 // CHECK-BASIC-LIBCXX-C-LINK: "--sysroot=[[SYSROOT]]"
 // CHECK-BASIC-LIBCXX-C-LINK: "-L[[SYSROOT]]/usr/bin/../lib"
 //
+// Test that libc++ combined with compiler-rt includes -lunwind
+// (and no gcc libraries).
+// RUN: %clangxx -no-canonical-prefixes -x c++ %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu \
+// RUN:     -stdlib=libc++ -rtlib=compiler-rt \
+// RUN:     -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/basic_linux_libcxx_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-CLANGRT %s
+// CHECK-BASIC-LIBCXX-CLANGRT: "-lc++"
+// CHECK-BASIC-LIBCXX-CLANGRT: "-lunwind"
+// CHECK-BASIC-LIBCXX-CLANGRT-NOT: "-lgcc_s"
+// CHECK-BASIC-LIBCXX-CLANGRT-NOT: "-lgcc"
+// CHECK-BASIC-LIBCXX-CLANGRT-NOT: "-lgcc_eh"
+//
+// Test that compiler-rt with -static includes -lunwind.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnu \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     --rtlib=compiler-rt \
+// RUN:     -static \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-STATIC-CLANGRT %s
+// CHECK-BASIC-STATIC-CLANGRT: "-lunwind"
+// CHECK-BASIC-STATIC-CLANGRT-NOT: "-lgcc_s"
+// CHECK-BASIC-STATIC-CLANGRT-NOT: "-lgcc"
+// CHECK-BASIC-STATIC-CLANGRT-NOT: "-lgcc_eh"
+//
 // Test a very broken version of multiarch that shipped in Ubuntu 11.04.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=i386-unknown-linux \
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -10220,6 +10220,7 @@
   // The profile runtime also needs access to system libraries.
   getToolChain().addProfileRTLibs(Args, CmdArgs);
 
+  bool NeedsUnwinder = false;
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
@@ -10230,14 +10231,20 @@
     if (OnlyLibstdcxxStatic)
       CmdArgs.push_back("-Bdynamic");
     CmdArgs.push_back("-lm");
+    // C++ always needs some unwinder
+    NeedsUnwinder = true;
   }
   // Silence warnings when linking C code with a C++ '-stdlib' argument.
   Args.ClaimAllArgs(options::OPT_stdlib_EQ);
 
   if (!Args.hasArg(options::OPT_nostdlib)) {
     if (!Args.hasArg(options::OPT_nodefaultlibs)) {
-      if (Args.hasArg(options::OPT_static))
+      if (Args.hasArg(options::OPT_static)) {
         CmdArgs.push_back("--start-group");
+        // when linking compiler-rt statically, we also need unwinder
+        // (note: this is implicit no-op for libgcc builds)
+        NeedsUnwinder = true;
+      }
 
       if (NeedsSanitizerDeps)
         linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
@@ -10278,6 +10285,11 @@
       }
 
       AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
+      // if unwinder is needed and we're using compiler-rt we need
+      // to explicitly link -lunwind in (libgcc has its own unwinder)
+      if (NeedsUnwinder && !isAndroid &&
+          ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT)
+        CmdArgs.push_back("-lunwind");
 
       if (WantPthread && !isAndroid)
         CmdArgs.push_back("-lpthread");


Index: test/Driver/linux-ld.c
===================================================================
--- test/Driver/linux-ld.c
+++ test/Driver/linux-ld.c
@@ -443,6 +443,34 @@
 // CHECK-BASIC-LIBCXX-C-LINK: "--sysroot=[[SYSROOT]]"
 // CHECK-BASIC-LIBCXX-C-LINK: "-L[[SYSROOT]]/usr/bin/../lib"
 //
+// Test that libc++ combined with compiler-rt includes -lunwind
+// (and no gcc libraries).
+// RUN: %clangxx -no-canonical-prefixes -x c++ %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu \
+// RUN:     -stdlib=libc++ -rtlib=compiler-rt \
+// RUN:     -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/basic_linux_libcxx_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-CLANGRT %s
+// CHECK-BASIC-LIBCXX-CLANGRT: "-lc++"
+// CHECK-BASIC-LIBCXX-CLANGRT: "-lunwind"
+// CHECK-BASIC-LIBCXX-CLANGRT-NOT: "-lgcc_s"
+// CHECK-BASIC-LIBCXX-CLANGRT-NOT: "-lgcc"
+// CHECK-BASIC-LIBCXX-CLANGRT-NOT: "-lgcc_eh"
+//
+// Test that compiler-rt with -static includes -lunwind.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnu \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     --rtlib=compiler-rt \
+// RUN:     -static \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-STATIC-CLANGRT %s
+// CHECK-BASIC-STATIC-CLANGRT: "-lunwind"
+// CHECK-BASIC-STATIC-CLANGRT-NOT: "-lgcc_s"
+// CHECK-BASIC-STATIC-CLANGRT-NOT: "-lgcc"
+// CHECK-BASIC-STATIC-CLANGRT-NOT: "-lgcc_eh"
+//
 // Test a very broken version of multiarch that shipped in Ubuntu 11.04.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=i386-unknown-linux \
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -10220,6 +10220,7 @@
   // The profile runtime also needs access to system libraries.
   getToolChain().addProfileRTLibs(Args, CmdArgs);
 
+  bool NeedsUnwinder = false;
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
@@ -10230,14 +10231,20 @@
     if (OnlyLibstdcxxStatic)
       CmdArgs.push_back("-Bdynamic");
     CmdArgs.push_back("-lm");
+    // C++ always needs some unwinder
+    NeedsUnwinder = true;
   }
   // Silence warnings when linking C code with a C++ '-stdlib' argument.
   Args.ClaimAllArgs(options::OPT_stdlib_EQ);
 
   if (!Args.hasArg(options::OPT_nostdlib)) {
     if (!Args.hasArg(options::OPT_nodefaultlibs)) {
-      if (Args.hasArg(options::OPT_static))
+      if (Args.hasArg(options::OPT_static)) {
         CmdArgs.push_back("--start-group");
+        // when linking compiler-rt statically, we also need unwinder
+        // (note: this is implicit no-op for libgcc builds)
+        NeedsUnwinder = true;
+      }
 
       if (NeedsSanitizerDeps)
         linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
@@ -10278,6 +10285,11 @@
       }
 
       AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
+      // if unwinder is needed and we're using compiler-rt we need
+      // to explicitly link -lunwind in (libgcc has its own unwinder)
+      if (NeedsUnwinder && !isAndroid &&
+          ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT)
+        CmdArgs.push_back("-lunwind");
 
       if (WantPthread && !isAndroid)
         CmdArgs.push_back("-lpthread");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D25402: [Driver... Michał Górny via Phabricator via cfe-commits

Reply via email to