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 \